Skip to content

Commit

Permalink
Adding support for updated command line args (#726)
Browse files Browse the repository at this point in the history
  • Loading branch information
shreyas-gopalakrishna committed Sep 14, 2023
1 parent ff172d5 commit b037e95
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 74 deletions.
173 changes: 99 additions & 74 deletions src/main/java/com/microsoft/azure/functions/worker/Application.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.microsoft.azure.functions.worker;

import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.*;
import javax.annotation.*;

import org.apache.commons.cli.*;
import org.apache.commons.lang3.exception.ExceptionUtils;

import static com.microsoft.azure.functions.worker.Constants.*;

/**
* The entry point of the Java Language Worker. Every component could get the command line options from this singleton
* Application instance, and typically that instance will be passed to your components as constructor arguments.
Expand All @@ -15,36 +20,17 @@ private Application(String[] args) {
this.parseCommandLine(args);
}

@Override
public String getHost() { return this.host; }
@Override
public int getPort() { return this.port; }
@Override
public boolean logToConsole() { return this.logToConsole; }
@Override
public Integer getMaxMessageSize() { return this.maxMessageSize; }
private String getWorkerId() { return this.workerId; }
private String getRequestId() { return this.requestId; }

private void printUsage() {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("Application", this.OPTIONS, true);
}

private boolean isCommandlineValid() { return this.commandParseSucceeded; }

@PostConstruct
private void parseCommandLine(String[] args) {
CommandLineParser parser = new DefaultParser();
try {
CommandLine commands = parser.parse(this.OPTIONS, args);
this.host = this.parseHost(commands.getOptionValue("h"));
this.port = this.parsePort(commands.getOptionValue("p"));
this.workerId = this.parseWorkerId(commands.getOptionValue("w"));
this.requestId = this.parseRequestId(commands.getOptionValue("q"));
this.logToConsole = commands.hasOption("l");
if (commands.hasOption("m")) {
this.maxMessageSize = this.parseMaxMessageSize(commands.getOptionValue("m"));
CommandLine commands = parser.parse(this.OPTIONS, args, true);
this.uri = this.parseUri(commands.getOptionValue(FUNCTIONS_URI_OPTION));
this.workerId = this.parseWorkerId(commands.getOptionValue(FUNCTIONS_WORKER_ID_OPTION));
this.requestId = this.parseRequestId(commands.getOptionValue(FUNCTIONS_REQUEST_ID_OPTION));
this.logToConsole = commands.hasOption(FUNCTIONS_CONSOLE_LOG_OPTION);
if (commands.hasOption(FUNCTIONS_GRPC_MAX_MESSAGE_LENGTH_OPTION)) {
this.maxMessageSize = this.parseMaxMessageSize(commands.getOptionValue(FUNCTIONS_GRPC_MAX_MESSAGE_LENGTH_OPTION));
}
this.commandParseSucceeded = true;
} catch (ParseException ex) {
Expand All @@ -53,84 +39,123 @@ private void parseCommandLine(String[] args) {
}
}

private String parseHost(String input) { return input; }

private int parsePort(String input) throws ParseException {
try {
int result = Integer.parseInt(input);
if (result < 1 || result > 65535) {
throw new IndexOutOfBoundsException("port number out of range");
public static void main(String[] args) {
WorkerLogManager.getSystemLogger().log(Level.INFO, "Azure Functions Java Worker version [ " + version() + "]");
Application app = new Application(args);
if (!app.isCommandlineValid()) {
app.printUsage();
System.exit(1);
} else {
try (JavaWorkerClient client = new JavaWorkerClient(app)) {
client.listen(app.getWorkerId(), app.getRequestId()).get();
} catch (Exception ex) {
WorkerLogManager.getSystemLogger().log(Level.SEVERE, ExceptionUtils.getRootCauseMessage(ex), ex);
System.exit(-1);
}
return result;
} catch (NumberFormatException | IndexOutOfBoundsException ex) {
throw new ParseException(String.format(
"port number \"%s\" is not qualified. It must be an integer within range [1, 65535]", input));
}
}

private String parseRequestId(String input) { return input; }

private String parseWorkerId(String input) { return input; }

private Integer parseMaxMessageSize(String input) {
return Integer.parseInt(input);
}

private boolean commandParseSucceeded = false;
private String host;
private String uri, host, workerId, requestId;
private int port;
private String workerId, requestId;
private boolean logToConsole;
private Integer maxMessageSize = null;

private final Options OPTIONS = new Options()
.addOption(Option.builder("h").longOpt("host")
.hasArg().argName("HostName")
.desc("The address of the machine that the Azure Functions host is running on")
.required()
.build())
.addOption(Option.builder("p").longOpt("port")
.hasArg().argName("PortNumber")
.desc("The port number which the Azure Functions host is listening to")
.addOption(Option.builder("u").longOpt(FUNCTIONS_URI_OPTION)
.hasArg().argName("Uri")
.desc("The uri of the machine that the Azure Functions host is running on")
.required()
.build())
.addOption(Option.builder("w").longOpt("workerId")
.addOption(Option.builder("w").longOpt(FUNCTIONS_WORKER_ID_OPTION)
.hasArg().argName("WorkerId")
.desc("The ID of this running worker throughout communication session")
.required()
.build())
.addOption(Option.builder("q").longOpt("requestId")
.addOption(Option.builder("q").longOpt(FUNCTIONS_REQUEST_ID_OPTION)
.hasArg().argName("RequestId")
.desc("The startup request ID of this communication session")
.required()
.build())
.addOption(Option.builder("l").longOpt("consoleLog")
.desc("Whether to duplicate all host logs to console as well")
.build())
.addOption(Option.builder("m").longOpt("grpcMaxMessageLength")
.addOption(Option.builder("l").longOpt(FUNCTIONS_GRPC_MAX_MESSAGE_LENGTH_OPTION)
.hasArg().argName("MessageSizeInBytes")
.desc("The maximum message size could be used by GRPC protocol")
.build())
.addOption(Option.builder("m").longOpt(FUNCTIONS_CONSOLE_LOG_OPTION)
.desc("Whether to duplicate all host logs to console as well")
.build());

@Override
public String getHost() {
return this.host;
}

public static void main(String[] args) {
WorkerLogManager.getSystemLogger().log(Level.INFO, "Azure Functions Java Worker version [ " + version() + "]");
Application app = new Application(args);
if (!app.isCommandlineValid()) {
app.printUsage();
System.exit(1);
} else {
try (JavaWorkerClient client = new JavaWorkerClient(app)) {
client.listen(app.getWorkerId(), app.getRequestId()).get();
} catch (Exception ex) {
WorkerLogManager.getSystemLogger().log(Level.SEVERE, ExceptionUtils.getRootCauseMessage(ex), ex);
System.exit(-1);
@Override
public int getPort() {
return this.port;
}

public String getUri() {
return this.uri;
}

@Override
public boolean logToConsole() {
return this.logToConsole;
}

@Override
public Integer getMaxMessageSize() {
return this.maxMessageSize;
}

private String getWorkerId() {
return this.workerId;
}

private String getRequestId() {
return this.requestId;
}

private boolean isCommandlineValid() {
return this.commandParseSucceeded;
}

private String parseUri(String uri) throws ParseException {
try {
URL url = new URL(uri);
url.toURI();
this.host = url.getHost();
this.port = url.getPort();
if (port < 1 || port > 65535) {
throw new IndexOutOfBoundsException("port number out of range");
}
return uri;
} catch (MalformedURLException | URISyntaxException | IndexOutOfBoundsException e) {
throw new ParseException(String.format(
"Error parsing URI \"%s\". Please provide a valid URI", uri));
}
}

private String parseRequestId(String input) {
return input;
}

private String parseWorkerId(String input) {
return input;
}

private Integer parseMaxMessageSize(String input) {
return Integer.parseInt(input);
}

public static String version() {
String jarVersion = Application.class.getPackage().getImplementationVersion();
return jarVersion != null && !jarVersion.isEmpty() ? jarVersion : "Unknown";
}

private void printUsage() {
HelpFormatter formatter = new HelpFormatter();
formatter.setWidth(100);
formatter.printHelp("Application", this.OPTIONS, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
*/
public final class Constants {
private Constants(){}

public final static String FUNCTIONS_URI_OPTION = "functions-uri";
public final static String FUNCTIONS_WORKER_ID_OPTION = "functions-worker-id";
public final static String FUNCTIONS_REQUEST_ID_OPTION = "functions-request-id";
public final static String FUNCTIONS_GRPC_MAX_MESSAGE_LENGTH_OPTION = "functions-grpc-max-message-length";
public final static String FUNCTIONS_CONSOLE_LOG_OPTION = "functions-console-log";
public final static String TRIGGER_METADATA_DOLLAR_REQUEST_KEY = "$request";
public final static String JAVA_LIBRARY_DIRECTORY = "/annotationLib";
public final static String JAVA_LIBRARY_ARTIFACT_ID = "azure-functions-java-library";
Expand Down

0 comments on commit b037e95

Please sign in to comment.