Skip to content

Commit

Permalink
Merged in PAYARA-3968-5.191.maintenance (pull request payara#727)
Browse files Browse the repository at this point in the history
PAYARA-3968 Payara Micro Postboot Script asadmin Commands Incorrect Quotation Mark Parsing (payara-server-5.191.maintenance)

Approved-by: David Matějček <david.matejcek@payara.fish>
Approved-by: Andrew Pielage <andrew.pielage@payara.fish>
  • Loading branch information
jGauravGupta authored and Pandrex247 committed Aug 19, 2019
2 parents 74225eb + 93e033c commit b7182d7
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 21 deletions.
Expand Up @@ -122,7 +122,7 @@ private void parseCommandLine(final String[] argv, final int start)

// is it an operand or option value?
if (!arg.startsWith("-") || arg.length() <= 1) {
operands.add(arg);
operands.add(StringUtils.trimQuotes(arg));
if (ignoreUnknown) {
continue;
}
Expand Down Expand Up @@ -339,7 +339,7 @@ private void setOption(ParamModel opt, String value) throws CommandValidationExc
throw new NullPointerException("null option name");
}
if (value != null) {
value = value.trim();
value = StringUtils.trimQuotes(value.trim());
}

String name = opt.getName();
Expand Down
Expand Up @@ -44,6 +44,9 @@
import static org.junit.Assert.*;

import java.util.Set;
import org.glassfish.api.admin.CommandValidationException;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.is;

/**
* A Junit4 test to test out the parser with various command lines. It works with examination of FirstPassResult
Expand All @@ -54,7 +57,26 @@
public class ParserTest {

@Test
public void dummy() { }
public void parseCommand() throws CommandValidationException {

String[] args = new String[]{
"create-custom-resource", "--restype", "java.lang.String",
"--enabled=true", "--name", "'custom-res'",
"--description", "\"results in error\"",
"--property", "value=\"${ENV=ini_ws_uri}\"",
"vfp/vfp-menu/ini.ws.uri"
};

Parser parse = new Parser(args, 0, null, true);

assertThat(parse.getOperands().size(), is(2));
assertThat(parse.getOptions().size(), is(5));

assertEquals(parse.getOperands().get(0), "create-custom-resource");
assertEquals(parse.getOptions().getOne("description"), "results in error");
assertEquals(parse.getOptions().getOne("name"), "custom-res");
}

/*
* Commented out until I get a chance to convert this to new classes.
@Test(expected = ParserException.class)
Expand Down
Expand Up @@ -771,4 +771,14 @@ public static String escapeForHtml(String str) {
public static String nvl(String str) {
return str == null ? "" : str;
}

public static String trimQuotes(String value) {
final int length = value.length();
if (length > 1
&& ((value.startsWith("\"") && value.endsWith("\"") && value.substring(1, length - 1).indexOf('"') == -1)
|| (value.startsWith("'") && value.endsWith("'") && value.substring(1, length - 1).indexOf('\'') == -1))) {
value = value.substring(1, length - 1);
}
return value;
}
}
Expand Up @@ -75,5 +75,13 @@ public boolean execute(CommandRunner runner) {
}
return result;
}


public String getCommand() {
return command;
}

public String[] getArguments() {
return arguments;
}

}
Expand Up @@ -44,12 +44,16 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import static java.util.logging.Level.SEVERE;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.glassfish.config.support.TranslatedConfigView;
import org.glassfish.embeddable.CommandRunner;

Expand All @@ -60,6 +64,14 @@
*/
public class BootCommands {

/**
* Command flag pattern include 3 groups to parse the command-line flag
* [^\"']\\S+=[\"'].+?[\"'] e.g --description="results in error"
* [^\"']\\S+ e.g --enabled=true, --enabled true
* [\"'].+?[\"'] e.g --description "results in error"
*
*/
private static final Pattern COMMAND_FLAG_PATTERN = Pattern.compile("([^\"']\\S+=[\"'].+?[\"']|[^\"']\\S+|[\"'].+?[\"'])\\s*");
private final List<BootCommand> commands;

private static final Logger LOGGER = Logger.getLogger(BootCommands.class.getName());
Expand All @@ -71,32 +83,46 @@ public BootCommands() {
public void add(BootCommand command) {
commands.add(command);
}


public List<BootCommand> getCommands() {
return commands;
}

public void parseCommandScript(File file) throws IOException {
parseCommandScript(file.toURI().toURL());
}

public void parseCommandScript(URL scriptURL) throws IOException {
try (InputStream scriptStream = scriptURL.openStream()) {
BufferedReader reader = new BufferedReader(new InputStreamReader(scriptStream));
Reader reader = new InputStreamReader(scriptStream);
parseCommandScript(reader);
} catch (IOException ex) {
LOGGER.log(SEVERE, null, ex);
}
}

String commandStr = reader.readLine();
while (commandStr != null) {
commandStr = commandStr.trim();
// # is a comment
if (commandStr.length() > 0 && !commandStr.startsWith("#")) {
commandStr = (String) TranslatedConfigView.getTranslatedValue(commandStr);
String command[] = commandStr.split(" ");
if (command.length > 1) {
commands.add(new BootCommand(command[0], Arrays.copyOfRange(command, 1, command.length)));
} else if (command.length == 1) {
commands.add(new BootCommand(command[0]));
}
void parseCommandScript(Reader reader) throws IOException {
BufferedReader bufferReader = new BufferedReader(reader);
String commandStr = bufferReader.readLine();
while (commandStr != null) {
commandStr = commandStr.trim();
// # is a comment
if (commandStr.length() > 0 && !commandStr.startsWith("#")) {
commandStr = (String) TranslatedConfigView.getTranslatedValue(commandStr);
String command[];
List<String> elements = new ArrayList<>();
Matcher flagMatcher = COMMAND_FLAG_PATTERN.matcher(commandStr);
while (flagMatcher.find()) {
elements.add(flagMatcher.group(1));
}
command = elements.toArray(new String[elements.size()]);
if (command.length > 1) {
commands.add(new BootCommand(command[0], Arrays.copyOfRange(command, 1, command.length)));
} else if (command.length == 1) {
commands.add(new BootCommand(command[0]));
}
commandStr = reader.readLine();
}
} catch (IOException ex) {
LOGGER.log(SEVERE, null, ex);
commandStr = bufferReader.readLine();
}
}

Expand Down
@@ -0,0 +1,76 @@
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) [2019] Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://github.com/payara/Payara/blob/master/LICENSE.txt
* See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* The Payara Foundation designates this particular file as subject to the "Classpath"
* exception as provided by the Payara Foundation in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package fish.payara.boot.runtime;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import org.junit.Test;

/**
*
* @author Gaurav Gupta
*/
public class BootCommandsTest {

@Test
public void parseCommand() throws IOException {
BootCommands bootCommands = new BootCommands();
String commandText = "create-custom-resource --restype java.lang.String --name='custom-res' --description=\"results in error\" --property value=\"${ENV=ini_ws_uri}\" vfp/vfp-menu/ini.ws.uri";
try (Reader reader = new StringReader(commandText)){
bootCommands.parseCommandScript(reader);
}
assertThat(bootCommands.getCommands().size(), is(1));

BootCommand command = bootCommands.getCommands().get(0);
assertThat(command.getArguments().length, is(7));
assertEquals(command.getArguments()[0], "--restype");
assertEquals(command.getArguments()[1], "java.lang.String");
assertEquals(command.getArguments()[2], "--name='custom-res'");
assertEquals(command.getArguments()[3], "--description=\"results in error\"");
assertEquals(command.getArguments()[4], "--property");
assertEquals(command.getArguments()[5], "value=\"${ENV=ini_ws_uri}\"");
assertEquals(command.getArguments()[6], "vfp/vfp-menu/ini.ws.uri");
}

}

0 comments on commit b7182d7

Please sign in to comment.