View Javadoc
1   /**
2    * This file Copyright (c) 2011-2017 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 Magnolia 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 Magnolia 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          return connect();
100     }
101 
102     /**
103      * Create a HTTP connection to the Magnolia server using a
104      * HTTP Form user/password authentification mechanism.
105      */
106     private boolean connect() {
107         // init
108         boolean res = false;
109         HttpPost httpost = null;
110         HttpResponse response = null;
111         HttpEntity entity = null;
112         log.debug("Try to connect to magnoliaUri='" + magnoliaUri);
113         // If still connected, Reconnect
114         if (isConnected()) {
115             log.warn("Still connected as we try to create a new connection. Will be disconnected first");
116             disconnect();
117         }
118 
119         try {
120             httpclient = new DefaultHttpClient();
121             // login post uri
122             httpost = new HttpPost(this.magnoliaUri + logingUri);
123             // in Parameter
124             List<NameValuePair> nvps = new ArrayList<NameValuePair>();
125             nvps.add(new BasicNameValuePair("mgnlUserId", this.user));
126             nvps.add(new BasicNameValuePair("mgnlUserPSWD", this.password));
127             httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
128             // request post
129             response = httpclient.execute(httpost);
130             // check and log result
131             System.out.println("Login form get: " + response.getStatusLine());
132             if (response.getStatusLine().toString().endsWith("200 OK")) {
133                 res = true;
134                 log.debug("Correctly connected to  magnoliaUri='" + magnoliaUri);
135             } else {
136                 log.warn("Could not establish a connection to magnoliaUri='" + magnoliaUri);
137             }
138             // Consume entity
139             entity = response.getEntity();
140             EntityUtils.consume(entity);
141 
142         } catch (ClientProtocolException cpe) {
143             log.error("", cpe);
144             /* As this is called by a standalone java application, error log will also be redirect to the console */
145             cpe.printStackTrace();
146         } catch (UnsupportedEncodingException uee) {
147             log.error("", uee);
148             /* As this is called by a standalone java application, error log will also be redirect to the console */
149             uee.printStackTrace();
150         } catch (IOException ioe) {
151             log.error("", ioe);
152             /* As this is called by a standalone java application, error log will also be redirect to the console */
153             ioe.printStackTrace();
154         }
155 
156         return res;
157     }
158 
159     /**
160      * Disconnect from Magnolia remote instance.
161      * 
162      * @return true if correctly disconnected
163      */
164     public boolean disconnect() {
165         boolean res = false;
166         if (httpclient != null && httpclient.getConnectionManager() != null) {
167             httpclient.getConnectionManager().shutdown();
168             log.debug("Correctly disconnected from magnoliaUri='" + magnoliaUri);
169             res = true;
170         }
171         return res;
172     }
173 
174     /**
175      * Check if still connected and authorized.
176      * 
177      * @return true if connected and authorized
178      */
179     public boolean isConnected() {
180         // init
181         boolean res = false;
182         HttpGet httpget = null;
183         HttpEntity entity = null;
184         try {
185             httpget = new HttpGet(magnoliaUri);
186             if (httpclient == null)
187                 return res;
188             HttpResponse response = httpclient.execute(httpget);
189 
190             // check if ended with 401 Unauthorized
191             if (!response.getStatusLine().toString().endsWith("401 Unauthorized")) {
192                 res = true;
193             }
194             // Consume entity
195             entity = response.getEntity();
196             EntityUtils.consume(entity);
197 
198         } catch (ClientProtocolException cpe) {
199             log.error("", cpe);
200             /* As this is called by a standalone java application, error log will also be redirect to the console */
201             cpe.printStackTrace();
202         } catch (UnsupportedEncodingException uee) {
203             log.error("", uee);
204             /* As this is called by a standalone java application, error log will also be redirect to the console */
205             uee.printStackTrace();
206         } catch (IOException ioe) {
207             log.error("", ioe);
208             /* As this is called by a standalone java application, error log will also be redirect to the console */
209             ioe.printStackTrace();
210         }
211 
212         return res;
213     }
214 
215     /**
216      * Execute the Groovy script defined in the incoming file in
217      * the Magnolia Groovy server environment.
218      * 
219      * @param inputObject absolute file name
220      * @return the script result as String
221      */
222     public String execute(Object inputObject) {
223         // init
224         HttpPost httpost = null;
225         HttpResponse response = null;
226         StringBuffer sb = new StringBuffer();
227         BufferedReader rd = null;
228         HttpEntity entity = null;
229 
230         try {
231             // login post uri
232             httpost = new HttpPost(magnoliaUri + groovyUri);
233             // in Parameter
234             List<NameValuePair> nvps = new ArrayList<NameValuePair>();
235             if (inputObject instanceof File) {
236                 nvps.add(new BasicNameValuePair("code", readFileAsString((File) inputObject)));
237             } else if (inputObject instanceof String) {
238                 nvps.add(new BasicNameValuePair("code", (String) inputObject));
239             } else {
240                 return "Input parameter is not a String or a File";
241             }
242             nvps.add(new BasicNameValuePair("command", "evaluateGroovy"));
243             httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
244             // request post
245             response = httpclient.execute(httpost);
246 
247             // Get the output
248             entity = response.getEntity();
249             if (entity != null) {
250                 // Get the response
251                 rd = new BufferedReader(new InputStreamReader(entity.getContent()));
252                 String line;
253                 while ((line = rd.readLine()) != null) {
254                     sb.append(line);
255                 }
256                 EntityUtils.consume(entity);
257             }
258             else {
259                 sb.append("No result");
260             }
261 
262         } catch (ClientProtocolException cpe) {
263             log.error("", cpe);
264             /* As this is called by a standalone java application, error log will also be redirect to the console */
265             cpe.printStackTrace();
266         } catch (UnsupportedEncodingException uee) {
267             log.error("", uee);
268             /* As this is called by a standalone java application, error log will also be redirect to the console */
269             uee.printStackTrace();
270         } catch (IOException ioe) {
271             log.error("", ioe);
272             /* As this is called by a standalone java application, error log will also be redirect to the console */
273             ioe.printStackTrace();
274         } finally {
275             if (rd != null) {
276                 try {
277                     rd.close();
278                 } catch (IOException e) {
279                     /* As this is called by a standalone java application, error log will also be redirect to the console */
280                     e.printStackTrace();
281                 }
282             }
283         }
284         return sb.toString();
285 
286     }
287 
288     /**
289      * Get a String representing the file content.
290      * 
291      * @throws java.io.IOException
292      */
293     private String readFileAsString(File file) throws java.io.IOException {
294         StringBuffer fileData = new StringBuffer(1000);
295         BufferedReader reader = null;
296         try {
297             reader = new BufferedReader(new FileReader(file));
298             char[] buf = new char[1024];
299             int numRead = 0;
300             while ((numRead = reader.read(buf)) != -1) {
301                 fileData.append(buf, 0, numRead);
302             }
303         } finally {
304             reader.close();
305         }
306 
307         return fileData.toString();
308     }
309 }