View Javadoc
1   /**
2    * This file Copyright (c) 2011-2015 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.module.groovy.remote;
35  
36  import java.io.BufferedReader;
37  import java.io.File;
38  import java.io.FileReader;
39  import java.io.IOException;
40  import java.io.InputStreamReader;
41  import java.io.UnsupportedEncodingException;
42  import java.util.ArrayList;
43  import java.util.List;
44  
45  import org.apache.http.HttpEntity;
46  import org.apache.http.HttpResponse;
47  import org.apache.http.NameValuePair;
48  import org.apache.http.client.ClientProtocolException;
49  import org.apache.http.client.entity.UrlEncodedFormEntity;
50  import org.apache.http.client.methods.HttpGet;
51  import org.apache.http.client.methods.HttpPost;
52  import org.apache.http.impl.client.DefaultHttpClient;
53  import org.apache.http.message.BasicNameValuePair;
54  import org.apache.http.protocol.HTTP;
55  import org.apache.http.util.EntityUtils;
56  import org.slf4j.Logger;
57  import org.slf4j.LoggerFactory;
58  
59  /**
60   * Remote client application connecting and executing Groovy Script against a
61   * Magnolia server instance.
62   */
63  public class RemoteClientConsole {
64  
65      private static final Logger log = LoggerFactory.getLogger(RemoteClientConsole.class);
66  
67      private final String logingUri = "/.magnolia/pages/adminCentral.html?";
68      private final String groovyUri = "/.magnolia/pages/groovyInteractiveConsole.html?";
69  
70      private DefaultHttpClient httpclient;
71      private String magnoliaUri;
72      private String user;
73      private String password;
74  
75      /**
76       * Parameter constructor.
77       * 
78       * @param magnoliaUri: Magnolia uri like http://localhost:8080/magnolia-empty-webapp
79       * @param user: Mgnolia admin user
80       * @param password: Magnolia admin user password
81       */
82      public RemoteClientConsole(String magnoliaUri, String user, String password) {
83          super();
84          connect(magnoliaUri, user, password);
85      }
86  
87      /**
88       * Create a HTTP connection to the Magnolia server using a
89       * HTTP Form user/password authentification mechanism.
90       * 
91       * @param magnoliaUri: Magnolia uri like http://localhost:8080/magnolia-empty-webapp
92       * @param user: Mgnolia admin user
93       * @param password: Magnolia admin user password
94       */
95      public boolean connect(String magnoliaUri, String user, String password) {
96          this.user = user;
97          this.password = password;
98          this.magnoliaUri = magnoliaUri;
99          log.debug("set private global variable magnoliaUri='" + magnoliaUri + "', user='" + user + "', passwoed='" + password + "'");
100         return connect();
101     }
102 
103     /**
104      * Create a HTTP connection to the Magnolia server using a
105      * HTTP Form user/password authentification mechanism.
106      */
107     private boolean connect() {
108         // init
109         boolean res = false;
110         HttpPost httpost = null;
111         HttpResponse response = null;
112         HttpEntity entity = null;
113         log.debug("Try to connect to magnoliaUri='" + magnoliaUri);
114         // If still connected, Reconnect
115         if (isConnected()) {
116             log.warn("Still connected as we try to create a new connection. Will be disconnected first");
117             disconnect();
118         }
119 
120         try {
121             httpclient = new DefaultHttpClient();
122             // login post uri
123             httpost = new HttpPost(this.magnoliaUri + logingUri);
124             // in Parameter
125             List<NameValuePair> nvps = new ArrayList<NameValuePair>();
126             nvps.add(new BasicNameValuePair("mgnlUserId", this.user));
127             nvps.add(new BasicNameValuePair("mgnlUserPSWD", this.password));
128             httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
129             // request post
130             response = httpclient.execute(httpost);
131             // check and log result
132             System.out.println("Login form get: " + response.getStatusLine());
133             if (response.getStatusLine().toString().endsWith("200 OK")) {
134                 res = true;
135                 log.debug("Correctly connected to  magnoliaUri='" + magnoliaUri);
136             } else {
137                 log.warn("Could not establish a connection to magnoliaUri='" + magnoliaUri);
138             }
139             // Consume entity
140             entity = response.getEntity();
141             EntityUtils.consume(entity);
142 
143         } catch (ClientProtocolException cpe) {
144             log.error("", cpe);
145             /* As this is called by a standalone java application, error log will also be redirect to the console */
146             cpe.printStackTrace();
147         } catch (UnsupportedEncodingException uee) {
148             log.error("", uee);
149             /* As this is called by a standalone java application, error log will also be redirect to the console */
150             uee.printStackTrace();
151         } catch (IOException ioe) {
152             log.error("", ioe);
153             /* As this is called by a standalone java application, error log will also be redirect to the console */
154             ioe.printStackTrace();
155         }
156 
157         return res;
158     }
159 
160     /**
161      * Disconnect from Magnolia remote instance.
162      * 
163      * @return: true if correctly disconnected
164      */
165     public boolean disconnect() {
166         boolean res = false;
167         if (httpclient != null && httpclient.getConnectionManager() != null) {
168             httpclient.getConnectionManager().shutdown();
169             log.debug("Correctly disconnected from magnoliaUri='" + magnoliaUri);
170             res = true;
171         }
172         return res;
173     }
174 
175     /**
176      * Check if still connected and authorized.
177      * 
178      * @return: true if connected and authorized
179      */
180     public boolean isConnected() {
181         // init
182         boolean res = false;
183         HttpGet httpget = null;
184         HttpEntity entity = null;
185         try {
186             httpget = new HttpGet(magnoliaUri);
187             if (httpclient == null)
188                 return res;
189             HttpResponse response = httpclient.execute(httpget);
190 
191             // check if ended with 401 Unauthorized
192             if (!response.getStatusLine().toString().endsWith("401 Unauthorized")) {
193                 res = true;
194             }
195             // Consume entity
196             entity = response.getEntity();
197             EntityUtils.consume(entity);
198 
199         } catch (ClientProtocolException cpe) {
200             log.error("", cpe);
201             /* As this is called by a standalone java application, error log will also be redirect to the console */
202             cpe.printStackTrace();
203         } catch (UnsupportedEncodingException uee) {
204             log.error("", uee);
205             /* As this is called by a standalone java application, error log will also be redirect to the console */
206             uee.printStackTrace();
207         } catch (IOException ioe) {
208             log.error("", ioe);
209             /* As this is called by a standalone java application, error log will also be redirect to the console */
210             ioe.printStackTrace();
211         }
212 
213         return res;
214     }
215 
216     /**
217      * Execute the Groovy script defined in the incoming file in
218      * the Magnolia Groovy server environment.
219      * 
220      * @param inputFile absolute file name
221      * @return the script result as String
222      */
223     public String execute(Object inputObject) {
224         // init
225         HttpPost httpost = null;
226         HttpResponse response = null;
227         StringBuffer sb = new StringBuffer();
228         BufferedReader rd = null;
229         HttpEntity entity = null;
230 
231         try {
232             // login post uri
233             httpost = new HttpPost(magnoliaUri + groovyUri);
234             // in Parameter
235             List<NameValuePair> nvps = new ArrayList<NameValuePair>();
236             if (inputObject instanceof File) {
237                 nvps.add(new BasicNameValuePair("code", readFileAsString((File) inputObject)));
238             } else if (inputObject instanceof String) {
239                 nvps.add(new BasicNameValuePair("code", (String) inputObject));
240             } else {
241                 return "Input parameter is not a String or a File";
242             }
243             nvps.add(new BasicNameValuePair("command", "evaluateGroovy"));
244             httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
245             // request post
246             response = httpclient.execute(httpost);
247 
248             // Get the output
249             entity = response.getEntity();
250             if (entity != null) {
251                 // Get the response
252                 rd = new BufferedReader(new InputStreamReader(entity.getContent()));
253                 String line;
254                 while ((line = rd.readLine()) != null) {
255                     sb.append(line);
256                 }
257                 EntityUtils.consume(entity);
258             }
259             else {
260                 sb.append("No result");
261             }
262 
263         } catch (ClientProtocolException cpe) {
264             log.error("", cpe);
265             /* As this is called by a standalone java application, error log will also be redirect to the console */
266             cpe.printStackTrace();
267         } catch (UnsupportedEncodingException uee) {
268             log.error("", uee);
269             /* As this is called by a standalone java application, error log will also be redirect to the console */
270             uee.printStackTrace();
271         } catch (IOException ioe) {
272             log.error("", ioe);
273             /* As this is called by a standalone java application, error log will also be redirect to the console */
274             ioe.printStackTrace();
275         } finally {
276             if (rd != null) {
277                 try {
278                     rd.close();
279                 } catch (IOException e) {
280                     /* As this is called by a standalone java application, error log will also be redirect to the console */
281                     e.printStackTrace();
282                 }
283             }
284         }
285         return sb.toString();
286 
287     }
288 
289     /**
290      * Get a String representing the file content.
291      * 
292      * @throws java.io.IOException
293      */
294     private String readFileAsString(File file) throws java.io.IOException {
295         StringBuffer fileData = new StringBuffer(1000);
296         BufferedReader reader = null;
297         try {
298             reader = new BufferedReader(new FileReader(file));
299             char[] buf = new char[1024];
300             int numRead = 0;
301             while ((numRead = reader.read(buf)) != -1) {
302                 fileData.append(buf, 0, numRead);
303             }
304         } finally {
305             reader.close();
306         }
307 
308         return fileData.toString();
309     }
310 }