Project

General

Profile

« Previous | Next » 

Revision f2808c21

Added by Andreas Kohlbecker over 3 years ago

ref #9181 DrushExecuter reading json values

View differences:

src/main/java/eu/etaxonomy/drush/DrushExecuter.java
25 25
import org.apache.log4j.Level;
26 26
import org.apache.log4j.Logger;
27 27

  
28
import com.fasterxml.jackson.core.type.TypeReference;
29
import com.fasterxml.jackson.databind.ObjectMapper;
30

  
28 31
/**
29 32
 * Java executor for drush (https://www.drush.org/).
30 33
 *
......
55 58
    }
56 59

  
57 60
    /**
58
     * List indexes returned from
59
     * <code>DrushExecuter.execute(DrushCommand cmd, String... value)</code>:
61
     * The execution of this command via
62
     * <code>DrushExecuter.execute({@linkplain DrushCommand#version})</code> results in
63
     * a {@code List<String>} return variable with the following elements:
60 64
     *
61 65
     * <ol>
62 66
     * <li>major</li>
......
72 76
    public static DrushCommand coreStatus = new DrushCommand(Arrays.asList("core-status"), null, null);
73 77

  
74 78
    /**
75
     * List indexes returned from
76
     * <code>DrushExecuter.execute(DrushCommand cmd, String... value)</code>:
77
     * Multiple matches are possible:
79
     * Executes {@code drush vget --exact <variable-key>}
80
     * <p>
81
     * The execution of this command via
82
     * <code>DrushExecuter.execute({@linkplain DrushCommand#variableSet})</code> results in
83
     * a {@code List<String>} return variable with the following elements:
84
     *
78 85
     * <ol>
79 86
     * <li>value</li>
80 87
     * <li>value</li>
81 88
     * <li>value</li>
82 89
     * <ol>
83 90
     */
84
    public static DrushCommand variableGet = new DrushCommand(Arrays.asList("vget", "%s"), ".*:\\s+'(?<value>.*)'",
85
            null);
86

  
91
    public static DrushCommand variableGet = new DrushCommand(Arrays.asList("vget", "--exact", "--format=json", "%s"));
87 92
    /**
88
     * List indexes returned from
89
     * <code>DrushExecuter.execute(DrushCommand cmd, String... value)</code>:
90
     * Multiple matches are possible:
93
     * Executes {@code drush vset --exact <variable-key> <variable-value>}
94
     * <p>
95
     * The execution of this command via
96
     * <code>DrushExecuter.execute({@linkplain DrushCommand#variableSet})</code> results in
97
     * a {@code List<String>} return variable with the following elements:
98
     *
91 99
     * <ol>
92 100
     * <li>value</li>
93 101
     * <li>status</li>
94 102
     * <ol>
95 103
     */
96 104
    public static DrushCommand variableSet = new DrushCommand(Arrays.asList("--yes", "vset", "%s", "%s"), null,
97
            "[^\\\"]*\\\"(?<value>.*)\\\"\\.\\s+\\[(?<status>\\w+)\\]");
105
            "[^\\\"]*\\\"(.*)\\\".*\\[(\\w+)\\]"
106
            );
98 107

  
99 108
    /**
100 109
     * @throws IOException
......
108 117
            throw new RuntimeException("not yet implmented for Windows");
109 118
        }
110 119

  
111
        List<String> matches = execute(version);
112
        assert !matches.get(0).isEmpty() : "No suitable drush command found in the system";
113
        String majorVersion = matches.get(0);
120
        List<Object> matches = execute(version);
121
        assert !((String) matches.get(0)).isEmpty() : "No suitable drush command found in the system";
122
        String majorVersion = (String) matches.get(0);
114 123
        if (Integer.valueOf(majorVersion) < 8) {
115 124
            throw new RuntimeException("drush version >= 8 required");
116 125
        }
......
123 132
     * @throws InterruptedException
124 133
     *             if the Process was interrupted
125 134
     */
126
    public List<String> execute(DrushCommand cmd, String... value) throws IOException, InterruptedException {
135
    public List<Object> execute(DrushCommand cmd, String... value) throws IOException, InterruptedException {
127 136

  
128 137
        List<String> executableWithArgs = new ArrayList<>();
129 138

  
......
154 163
            }
155 164
        }
156 165

  
157
        List<String> matches = new ArrayList<>();
166
        List<Object> matches = new ArrayList<>();
158 167

  
159 168
        ProcessBuilder pb = new ProcessBuilder(executableWithArgs);
160 169
        logger.debug("Command: " + pb.command().toString());
......
162 171
        int exitCode = process.waitFor();
163 172

  
164 173
        if (exitCode == 0) {
165
            String out = readExecutionResponse(matches, process.getInputStream(), cmd.outRegex);
166
            String error = readExecutionResponse(matches, process.getErrorStream(), cmd.errRegex);
174
            String out, error;
175
            if(cmd.jsonResult) {
176
                out = readExecutionResponse(matches, process.getInputStream());
177
                error = readExecutionResponse(matches, process.getErrorStream());
178
            } else {
179
                out = readExecutionResponse(matches, process.getInputStream(), cmd.outRegex);
180
                error = readExecutionResponse(matches, process.getErrorStream(), cmd.errRegex);
181
            }
167 182
            if (out != null && !out.isEmpty()) {
168 183
                logger.error(error);
169 184
            }
......
176 191
        return matches;
177 192
    }
178 193

  
179
    protected String readExecutionResponse(List<String> matches, InputStream stream, Pattern regex) throws IOException {
194
    protected String readExecutionResponse(List<Object> matches, InputStream stream, Pattern regex) throws IOException {
180 195
        String out;
181 196
        if (regex != null) {
182 197
            Scanner scanner = new Scanner(stream);
......
209 224
            logger.debug(out);
210 225
            return out;
211 226
        }
227
    }
212 228

  
229
    /**
230
     * @param matches
231
     * @param stream
232
     * @return depending on the drupal variable type different return types are possible:
233
     *  <ul>
234
     *  <li>Object</li>
235
     *  <li>List</li>
236
     *  <li>List</li>
237
     *  <li>String</li>
238
     *  <li>Double</li>
239
     *  <li>Integer</li>
240
     *  </ul>
241
     *
242
     * @throws IOException
243
     */
244
    protected String readExecutionResponse(List<Object> matches, InputStream stream) throws IOException {
245
        String out = IOUtils.toString(stream);
246
        if(out != null) {
247
            out = out.trim();
248
            if(!out.isEmpty()) {
249
                ObjectMapper mapper = new ObjectMapper();
250
                if(out.startsWith("[")) {
251
                   matches.add(mapper.readValue(out, new TypeReference<List<Object>>(){}));
252
                } else  {
253
                   matches.add(mapper.readValue(out, Object.class));
254
                }
255
                if(matches.isEmpty()) {
256
                    logger.debug("no result");
257
                } else {
258
                    logger.debug("result object: " + matches.get(0));
259
                }
260
            }
261

  
262
        }
263
        return out;
213 264
    }
214 265

  
215 266
    public static class DrushCommand {
216 267

  
217 268
        Pattern outRegex;
218 269
        Pattern errRegex;
270
        boolean jsonResult = false;
219 271
        List<String> args = new ArrayList<>();
220 272

  
221 273
        public DrushCommand(List<String> args, String outRegex, String errRegex) {
......
227 279
                this.errRegex = Pattern.compile(errRegex, Pattern.MULTILINE);
228 280
            }
229 281
        }
282

  
283
        /**
284
         * For drush commands suopporting the {@code --format=json} option.
285
         * @param args
286
         */
287
        public DrushCommand(List<String> args) {
288
            this.args = args;
289
            this.jsonResult = true;
290
        }
230 291
    }
231 292

  
232 293
    /**
......
239 300
        DrushExecuter.logger.setLevel(Level.DEBUG);
240 301
        try {
241 302
            DrushExecuter dex = new DrushExecuter();
303
            List<Object> results;
242 304
            dex.setDrupalRoot(new File("/home/andreas/workspaces/www/drupal-7"));
243 305
            dex.setSiteURI(new URI("http://edit.test/d7/caryophyllales/"));
244
            dex.execute(coreStatus);
245
            dex.execute(help);
246
            List<String> results = dex.execute(variableSet, "cdm_webservice_url",
306
//            dex.execute(coreStatus);
307
//            dex.execute(help);
308
            results = dex.execute(variableSet, "cdm_webservice_url",
247 309
                    "http://api.cybertaxonomy.org/cyprus/");
248 310
            if (!results.get(0).equals("http://api.cybertaxonomy.org/cyprus/")) {
249 311
                throw new RuntimeException("unexpected result item 0: " + results.get(0));
......
251 313
            if (!results.get(1).equals("success")) {
252 314
                throw new RuntimeException("unexpected result item 1: " + results.get(0));
253 315
            }
316
            results = dex.execute(variableGet, "cdm_webservice_url");
317
            if (!results.get(0).equals("http://api.cybertaxonomy.org/cyprus/")) {
318
                throw new RuntimeException("unexpected result item 0: " + results.get(0));
319
            }
254 320
            // testing remote execution via ssh
255 321
            dex.sshHost = "edit-int";
256 322
            dex.setDrupalRoot(new File("/var/www/drupal-7"));

Also available in: Unified diff