- 
                Notifications
    You must be signed in to change notification settings 
- Fork 153
WIP: Generate native binary from java code #2302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
WIP: Generate native binary from java code #2302
Conversation
| /cc @SandraAhlgrimm | 
| 
 @microsoft-github-policy-service agree company="Red Hat" | 
| Converting to Draft. I'll seek guidance from @Flanker32 , but in general I am in favor of this feature. | 
| final boolean isDeployToFunctionSlot = getDeploymentSlotSetting() != null && StringUtils.isNotEmpty(getDeploymentSlotSetting().getName()); | ||
| result.put(FUNCTION_DEPLOY_TO_SLOT_KEY, String.valueOf(isDeployToFunctionSlot)); | ||
| result.put(FUNCTION_IS_NATIVE_EXECUTABLE, String.valueOf(isNativeExecutable())); | ||
| result.put(FUNCTION_CUSTOM_HANDLER_ARGS, customHandlerArgs); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will ‘customHandlerArgs’ contains any PII data like file location? If so, we should not record them in telemetry but we could track whether users set custom handler args here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I don't know. Do you suggest to remove both lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to keep line 357, so that we could track how many users use native executable, for custom handler args, I'm not sure whether we need track it, so may be it could be removed
        
          
                azure-functions-maven-plugin/src/main/java/com/microsoft/azure/maven/function/PackageMojo.java
              
                Outdated
          
            Show resolved
            Hide resolved
        
              
          
                ...e-lib/src/main/java/com/microsoft/azure/toolkit/lib/appservice/config/FunctionAppConfig.java
              
                Outdated
          
            Show resolved
            Hide resolved
        
      | return result; | ||
| } | ||
|  | ||
| protected String finalNameWithExtension() { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getArtifact will be called by compile level validation and the function.json generation logic, we may be careful to modify its implementation. It seems that this method will only be called during function package, so could we just move this method to Package.mojo, and modify copyBinaryToStageDirectoryto get the correct artifact?
Besides, we may add a parameter like nativeExecutablePath' instead of boolean nativeExecutable`, as we could only guess the final artifact here, but users may modify it with configuration in quarkus maven plugin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, just to validate if I understand all:
- Move getArtifact from AbstractFunctionMojo to Package
- change nativeExecutable to nativeExecutablePath, and if nativeExecutablePath is defined, I will call copyBinaryToStageDirectory instead copyJarsToStageDirectory
Correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I prefer to keep getArtifactas it is, and move binary related logic tocopyBinaryToStageDirectoryin package mojo.
- Yes, I think nativeExecutablePathmay be more flexible, and we no longer need to generate the path for executable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Flanker32 , I did not test all the changes yet.
| final File sourceLocalSettingsJsonFile = getLocalSettingsJsonFile(); | ||
| final File destLocalSettingsJsonFile = Paths.get(getDeploymentStagingDirectoryPath(), LOCAL_SETTINGS_JSON).toFile(); | ||
| copyFilesWithDefaultContent(sourceLocalSettingsJsonFile, destLocalSettingsJsonFile, DEFAULT_LOCAL_SETTINGS_JSON); | ||
| String defaultContent = MessageFormat.format(DEFAULT_LOCAL_SETTINGS_JSON, getWorkerRuntime()); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to overwrite users configuration for native artifact? As default content will not work if users have a local.settings.json in their workspace. Same for the host.json
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have one newbie question: local.settins.json is enough to test locally (without host.json)?
I think the plugin should not overwrite any json files created by the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you can test locally without the host.json file.
local.settings.json is used for local development and will not be published to Azure. [On the other hand, host.json is used for configuring the Functions host process when you run projects locally and in Azure, for log level for instance]
https://learn.microsoft.com/en-us/azure/azure-functions/functions-develop-local
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@viniciusfcf @SandraAhlgrimm Thank you all for your help. Just want to confirm whether customHandler configuration is required in host.json? I just tried to remove following configuration and func seems broken.
If its required, do we need to add validation throw exception if user did not set it in host.json? Besides, I'm not sure whether we should provide default configuration as the following configuration should only works for quarkus, or is there any way we could detect whether the binary is a quarkus one or spring boot?
    "customHandler": {
        "description": {
            "defaultExecutablePath": "quarkus-azure-functions-http-1.0.0-SNAPSHOT",
            "workingDirectory": "",
            "arguments": [
                "-Dquarkus.http.port=${FUNCTIONS_CUSTOMHANDLER_PORT}"
            ]
        },
        "enableForwardingHttpRequest": true
    }
| @viniciusfcf Thanks a lot for your efforts! Please see my comments in this PR. 
 Tried fixes in quarkusio/quarkus#33681, it works fine now | 
328dde5    to
    b5187b2      
    Compare
  
    b5187b2    to
    98db9fe      
    Compare
  
    98db9fe    to
    fd601b1      
    Compare
  
    | 
 Can we convert back to Open PR please 👍 | 
| } | ||
|  | ||
| protected boolean isNativeExecutable() { | ||
| return StringUtils.isEmpty(getNativeExecutablePath()); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be isNotEmpty?
| result.put(DISABLE_APP_INSIGHTS_KEY, String.valueOf(isDisableAppInsights())); | ||
| final boolean isDeployToFunctionSlot = getDeploymentSlotSetting() != null && StringUtils.isNotEmpty(getDeploymentSlotSetting().getName()); | ||
| result.put(FUNCTION_DEPLOY_TO_SLOT_KEY, String.valueOf(isDeployToFunctionSlot)); | ||
| result.put(FUNCTION_NATIVE_EXECUTABLE_PATH, nativeExecutablePath); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please just track isNativeExecutable as path may include pii data
| @viniciusfcf @SandraAhlgrimm Thank you all for your help and efforts. Please see my comments in the PR. Besides, for the configuration in host.json, just want to confirm whether customHandler configuration is required in host.json? If so, I think we should add validation in native binary cases and throw exception if use did not set it or the host.json is missing, as it seems that we could not provide a default configuration for this case (the default configuration in this PR seems only works for quarkus. | 
7bc506a    to
    d87d3b8      
    Compare
  
    | @agoncal for review | 
891656f    to
    4489749      
    Compare
  
    4489749    to
    3d95343      
    Compare
  
    | private boolean disableAppInsights; | ||
| private String storageAccountName; | ||
| private String storageAccountResourceGroup; | ||
| private String nativeExecutablePath; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove these new parameters as FunctionAppConfig is used to create resource in Azure, which should not contains native binary configurations
Checkstyle is not ok.
What does this implement/fix? Explain your changes.
Java projects could generate jar or native files to run (Quarkus, Micronaut or SpringBoot). Now it's very easy after accept this PR. Example with Quarkus using this plugin: https://github.com/viniciusfcf/quarkus-azure-functions-http/tree/using-new-versions
…
Does this close any currently open issues?
No, however I'm working with Sandra Ahlgrimm to allow native function using customHandler from java projects
Any relevant logs, screenshots, error output, etc.?
Any other comments?
…
Has this been tested?