View Javadoc
1   /*
2    * Copyright (c) 2002-2014, 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.dila.service.impl;
35  
36  import fr.paris.lutece.plugins.dila.exception.DilaException;
37  import fr.paris.lutece.plugins.dila.service.IDilaDownloadService;
38  import fr.paris.lutece.plugins.dila.utils.constants.DilaConstants;
39  import fr.paris.lutece.plugins.dila.utils.http.HttpRequestInterceptorBzip2;
40  import fr.paris.lutece.plugins.dila.utils.http.HttpResponseInterceptorBzip2;
41  import fr.paris.lutece.portal.service.util.AppLogService;
42  import fr.paris.lutece.portal.service.util.AppPropertiesService;
43  
44  import org.apache.commons.compress.utils.IOUtils;
45  import org.apache.commons.io.FileUtils;
46  import org.apache.commons.io.FilenameUtils;
47  import org.apache.commons.lang.StringUtils;
48  
49  import org.apache.http.HttpHost;
50  import org.apache.http.auth.AuthScope;
51  import org.apache.http.auth.UsernamePasswordCredentials;
52  import org.apache.http.client.ClientProtocolException;
53  import org.apache.http.client.CredentialsProvider;
54  import org.apache.http.client.config.RequestConfig;
55  import org.apache.http.client.methods.CloseableHttpResponse;
56  import org.apache.http.client.methods.HttpGet;
57  import org.apache.http.impl.client.BasicCredentialsProvider;
58  import org.apache.http.impl.client.CloseableHttpClient;
59  import org.apache.http.impl.client.HttpClientBuilder;
60  import org.apache.http.impl.client.HttpClients;
61  
62  import java.io.BufferedInputStream;
63  import java.io.BufferedOutputStream;
64  import java.io.File;
65  import java.io.FileNotFoundException;
66  import java.io.FileOutputStream;
67  import java.io.IOException;
68  
69  import java.net.HttpURLConnection;
70  
71  
72  /**
73   * Implementation of {@link IDilaDownloadService}
74   */
75  public class DilaDownloadService implements IDilaDownloadService
76  {
77      private static final String HTTP_ACCESS_PROXY_PASSWORD = "httpAccess.proxyPassword";
78      private static final String HTTP_ACCESS_PROXY_USERNAME = "httpAccess.proxyUserName";
79      private static final String HTTP_ACCESS_PROXY_PORT = "httpAccess.proxyPort";
80      private static final String HTTP_ACCESS_PROXY_HOST = "httpAccess.proxyHost";
81  
82      @Override
83      public void downloadAll(  ) throws DilaException
84      {
85          // individuals
86          download( AppPropertiesService.getProperty( DilaConstants.PROPERTY_XML_URL_INDIVIDUALS ),
87              AppPropertiesService.getProperty( DilaConstants.PROPERTY_XML_NAME_INDIVIDUALS ) );
88          // associations
89          download( AppPropertiesService.getProperty( DilaConstants.PROPERTY_XML_URL_ASSO ),
90              AppPropertiesService.getProperty( DilaConstants.PROPERTY_XML_NAME_ASSO ) );
91          // professionnals
92          download( AppPropertiesService.getProperty( DilaConstants.PROPERTY_XML_URL_PME ),
93              AppPropertiesService.getProperty( DilaConstants.PROPERTY_XML_NAME_PME ) );
94          // local
95          download( AppPropertiesService.getProperty( DilaConstants.PROPERTY_XML_URL_LOCALES ),
96              AppPropertiesService.getProperty( DilaConstants.PROPERTY_XML_NAME_LOCALES ) );
97      }
98  
99      /**
100      * Download one file
101      * @param strArchiveUrl the url
102      * @param strArchiveName the name
103      * @throws DilaException daemon error
104      */
105     private void download( String strArchiveUrl, String strArchiveName )
106         throws DilaException
107     {
108         CloseableHttpClient client = null;
109         HttpClientBuilder clientBuilder = HttpClients.custom(  );
110         HttpGet request = new HttpGet( strArchiveUrl + strArchiveName );
111         String proxyHost = AppPropertiesService.getProperty( HTTP_ACCESS_PROXY_HOST );
112 
113         // Connection through proxy
114         if ( StringUtils.isNotBlank( proxyHost ) )
115         {
116             String proxyPort = AppPropertiesService.getProperty( HTTP_ACCESS_PROXY_PORT );
117             String proxyUser = AppPropertiesService.getProperty( HTTP_ACCESS_PROXY_USERNAME );
118             String proxyPassword = AppPropertiesService.getProperty( HTTP_ACCESS_PROXY_PASSWORD );
119 
120             //Proxy authentication
121             if ( StringUtils.isNotBlank( proxyUser ) )
122             {
123                 CredentialsProvider credsProvider = new BasicCredentialsProvider(  );
124                 credsProvider.setCredentials( new AuthScope( proxyHost, Integer.parseInt( proxyPort ) ),
125                     new UsernamePasswordCredentials( proxyUser, proxyPassword ) );
126                 clientBuilder.setDefaultCredentialsProvider( credsProvider );
127             }
128 
129             String strSchema = request.getURI(  ).getScheme(  );
130             HttpHost proxy = new HttpHost( proxyHost, Integer.parseInt( proxyPort ), strSchema );
131             RequestConfig config = RequestConfig.custom(  ).setProxy( proxy ).build(  );
132             request.setConfig( config );
133         }
134 
135         // Special header to download bzip2
136         if ( strArchiveName.endsWith( ".bz2" ) )
137         {
138             clientBuilder.addInterceptorFirst( new HttpRequestInterceptorBzip2(  ) )
139                          .addInterceptorFirst( new HttpResponseInterceptorBzip2(  ) );
140         }
141 
142         // Build client
143         client = clientBuilder.build(  );
144 
145         CloseableHttpResponse response = null;
146 
147         try
148         {
149             response = client.execute( request );
150         }
151         catch ( ClientProtocolException e )
152         {
153             AppLogService.error( "Error on HTTP protocol" );
154             throw new DilaException( "Error on HTTP protocol" );
155         }
156         catch ( IOException e )
157         {
158             AppLogService.error( "Error on HTTP protocol" );
159             throw new DilaException( "Error on HTTP protocol" );
160         }
161 
162         // Get response status
163         int nResponseStatusCode = response.getStatusLine(  ).getStatusCode(  );
164         AppLogService.debug( "Response status : " + nResponseStatusCode );
165 
166         if ( nResponseStatusCode != HttpURLConnection.HTTP_OK )
167         {
168             AppLogService.debug( "Error URL connection status != " + HttpURLConnection.HTTP_OK );
169         }
170 
171         // Buffer response
172         BufferedInputStream bis = null;
173 
174         try
175         {
176             bis = new BufferedInputStream( response.getEntity(  ).getContent(  ) );
177         }
178         catch ( Exception e )
179         {
180             AppLogService.error( "Error on get reponse entity content" );
181             throw new DilaException( "Error on get reponse entity content" );
182         }
183 
184         String strArchivesDirPath = AppPropertiesService.getProperty( DilaConstants.PROPERTY_TMP_DIRECTORY );
185 
186         String strFileZipPathName = FilenameUtils.concat( strArchivesDirPath, strArchiveName );
187         File fileZip = new File( strFileZipPathName );
188         File dirZip = new File( strArchivesDirPath );
189 
190         if ( ( dirZip != null ) && !dirZip.exists(  ) )
191         {
192             AppLogService.debug( "Create directory to save archives : " + strArchivesDirPath );
193 
194             try
195             {
196                 FileUtils.forceMkdir( dirZip );
197             }
198             catch ( IOException e )
199             {
200                 AppLogService.error( "Error on create directory archives" );
201                 throw new DilaException( "Error on create directory archives" );
202             }
203         }
204 
205         BufferedOutputStream bos = null;
206 
207         try
208         {
209             bos = new BufferedOutputStream( new FileOutputStream( fileZip ) );
210         }
211         catch ( FileNotFoundException e )
212         {
213             AppLogService.error( "Error on create archive." );
214             throw new DilaException( "Error on create archive." );
215         }
216 
217         try
218         {
219             IOUtils.copy( bis, bos );
220         }
221         catch ( IOException e )
222         {
223             AppLogService.error( "Error on copy input to output stream" );
224             throw new DilaException( "Error on copy input to output stream" );
225         }
226 
227         // Close response
228         try
229         {
230             response.close(  );
231         }
232         catch ( IOException e )
233         {
234             AppLogService.error( "Error on close response" );
235             throw new DilaException( "Error on close response" );
236         }
237 
238         // Close output buffer
239         try
240         {
241             bos.close(  );
242         }
243         catch ( IOException e )
244         {
245             AppLogService.error( "Error on close output stream" );
246             throw new DilaException( "Error on close output stream" );
247         }
248 
249         // Close input buffer
250         try
251         {
252             bis.close(  );
253         }
254         catch ( IOException e )
255         {
256             AppLogService.error( "Error on close input stream" );
257             throw new DilaException( "Error on close input stream" );
258         }
259 
260         // Close client connection
261         try
262         {
263             client.close(  );
264         }
265         catch ( IOException e )
266         {
267             AppLogService.error( "Error on close http client" );
268             throw new DilaException( "Error on close http client" );
269         }
270     }
271 }