Java函数开发指南(使用IDEA工具创建Java工程)
FunctionGraph目前支持以下Java运行环境。
- Java 8 (runtime = Java8)
- Java 11(runtime = Java11)
- Java 17(runtime = Java17)
- Java 21(runtime = Java21)(仅支持“中东-利雅得”、“土耳其-伊斯坦布尔”区域)
Java函数接口定义
Java函数接口定义:作用域 返回参数 函数名(函数参数,Context参数)
- 作用域:提供给FunctionGraph调用的用户函数必须定义为public。
- 返回参数:用户定义,FunctionGraph负责转换为字符串,作为HTTP Response返回。对于返回参数对象类型,HTTP Response该类型的JSON字符串。
- 函数名:用户定义函数名称。
- 函数参数:用户定义参数,当前函数仅支持一个用户参数。对于复杂参数,建议定义为对象类型,以JSON字符串提供数据。FunctionGraph调用函数时,解析JSON为对象。
- Context:runtime提供函数执行上下文,其接口定义在SDK接口说明。
Java函数的函数执行入口参数格式为:[包名].[类名].[执行函数名],请参考函数执行入口进行配置或修改。
约束与限制
getToken()、getAccessKey()和getSecretKey()方法返回的内容包含敏感信息,请谨慎使用,避免造成敏感信泄露。
Java的initializer入口介绍
Initializer格式为:[包名].[类名].[执行函数名]
示例:创建函数时指定的initializer为com.huawei.Demo.my_initializer,那么FunctionGraph会去加载com.huawei包,Demo类中定义的my_initializer函数。
在函数工作流服务中使用Java实现initializer接口,需要定义一个java函数作为initializer入口,以下为initializer的简单示例。
public void my_initializer(Context context)
{
RuntimeLogger log = context.getLogger();
log.log(String.format("ak:%s", context.getAccessKey()));
}
步骤一:使用IDEA创建Java工程
- 配置IDEA
- 添加工程依赖
根据Java SDK下载提供的SDK地址,下载JavaRuntime SDK到本地开发环境解压,如图2所示。
- 配置依赖
在工程目录下创建lib目录,将zip中的Runtime2.0.5.jar和代码所需要的三方依赖包拷贝到该目录,并把该jar添加为工程依赖,如图3所示。
- 配置函数资源
创建包com.huawei.demo,并在包下创建TriggerTests类,如图4所示。
- 配置函数代码
如图5所示,在TriggerTests.java中定义函数运行入口,示例代码如下。(普通java项目需要通过Artifacts来进行编译,因此需要定义一个main函数。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
package com.huawei.demo; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import com.huawei.services.runtime.Context; import com.huawei.services.runtime.entity.apig.APIGTriggerEvent; import com.huawei.services.runtime.entity.apig.APIGTriggerResponse; import com.huawei.services.runtime.entity.dis.DISTriggerEvent; import com.huawei.services.runtime.entity.dms.DMSTriggerEvent; import com.huawei.services.runtime.entity.lts.LTSTriggerEvent; import com.huawei.services.runtime.entity.smn.SMNTriggerEvent; import com.huawei.services.runtime.entity.timer.TimerTriggerEvent; public class TriggerTests { public static void main(String args[]) {} public APIGTriggerResponse apigTest(APIGTriggerEvent event, Context context){ System.out.println(event); Map<String, String> headers = new HashMap<String, String>(); headers.put("Content-Type", "application/json"); return new APIGTriggerResponse(200, headers, event.toString()); } public String smnTest(SMNTriggerEvent event, Context context){ System.out.println(event); return "ok"; } public String dmsTest(DMSTriggerEvent event, Context context){ System.out.println(event); return "ok"; } public String timerTest(TimerTriggerEvent event, Context context){ System.out.println(event); return "ok"; } public String disTest(DISTriggerEvent event, Context context) throws UnsupportedEncodingException{ System.out.println(event); System.out.println(event.getMessage().getRecords()[0].getRawData()); return "ok"; } public String ltsTest(LTSTriggerEvent event, Context context) throws UnsupportedEncodingException { System.out.println(event); event.getLts().getData(); System.out.println("raw data: " + event.getLts().getRawData()); return "ok"; } }
示例代码中添加了多个入口函数,分别使用了不同的触发器事件类型,可通过FunctionGraph控制台修改函数执行入口测试不同的入口函数。当函数的事件源是APIG时,相关约束条件请参考Base64解码和返回结构体的说明。
说明:
修改函数执行入口:
在FunctionGraph控制台左侧导航栏选择“函数 > 函数列表”,单击需要设置的“函数名称”进入函数详情页,选择“设置 > 常规设置”,配置“函数执行入口”参数,如图6所示。
步骤三:创建Java函数并测试
- 登录函数工作流控制台,左侧导航栏选择 ,单击右上角“创建函数”进入创建函数页面,选择“创建空白函数”。
- 如图11所示,配置函数基本信息,配置完成后单击右下角“创建函数”完成创建。
- 进入函数详情页,在“代码”页签下,单击右侧 ,如图12所示,添加步骤二:打包Java工程的JAR文件上传。
- 上传成功后,选择“设置 > 常规设置”,修改需要测试的函数执行入口参数,单击 。
- 回到“代码”页签,单击代码编辑区的“测试”,选择“创建新的测试事件”,在云事件模板列表中选择需要测试的事件模板,单击“创建”。
- 单击“测试”,查看函数执行结果。
函数执行结果分为三部分,分别为函数返回(由callback返回)、执行摘要、日志输出(由console.log或getLogger()方法获取的日志方法输出),参考表1查看结果说明。
表1 执行结果说明 参数项
执行成功
执行失败
函数返回
返回函数中定义的返回信息。
返回包含错误信息和堆栈异常报错信息的JSON文件。格式如下:
{ "errorMessage": "", "stackTrace": [] }
errorMessage:Runtime返回的错误信息
stackTrace:Runtime返回的堆栈异常报错信息
执行摘要
显示请求ID、配置内存、执行时长、实际使用内存和收费时长。
显示请求ID、配置内存、执行时长、实际使用内存和收费时长。
日志
打印函数日志,最多显示4KB的日志。
打印报错信息,最多显示4KB的日志。
说明:
如需测试示例代码中的其他事件源触发器,例如SMN事件源,可在函数的常规设置中,将函数执行入口修改为com.huawei.demo.TriggerTests.smnTest,并参考以上步骤,创建新的消息通知服务SMN测试事件进行函数测试。
SDK接口
FunctionGraph函数JavaSDK提供了Event事件接口、Context接口和日志记录接口,SDK下载地址见Java SDK下载(校验文件:fss-java-sdk-2.0.5.sha256)。
- Event事件接口
Java SDK引入了触发器事件结构体定义,当前支持DMS、DIS、SMN、TIMER、APIG、Kafka。在需要使用触发器的场景下,编写相应代码更简便。
- APIG触发器相关方法说明
- APIGTriggerEvent相关方法说明
表2 APIGTriggerEvent相关方法说明 方法名
方法说明
isBase64Encoded()
Event中的body是否是base64编码。
getHttpMethod()
获取Http请求方法。
getPath()
获取Http请求路径。
getBody()
获取Http请求body。
getPathParameters()
获取所有路径参数。
getRequestContext()
获取相关的APIG配置。(返回APIGRequestContext对象)
getHeaders()
获取Http请求头。
getQueryStringParameters()
获取查询参数。
当前查询参数不支持取值为数组,如果查询参数的取值需要为数组,请自定义对应的触发器事件结构体。
getRawBody()
获取base64编码前的内容。
getUserData()
获取APIG自定义认证中设置的userdata。
- APIGTriggerResponse相关方法说明
表4 APIGTriggerResponse构造方法说明 方法名
方法说明
无参构造APIGTriggerResponse()
其中headers设置为null,statusCode设置为200,body设置为" ",isBase64Encoded设置为false。
三个参数构造APIGTriggerResponse(statusCode, headers, body)
isBase64Encoded设置为false,其他均以输入为准。
四个参数构造APIGTriggerResponse(statusCode, headers, isBase64Encoded, body)
按照对应顺序设置值即可。
表5 APIGTriggerResponse相关方法说明 方法名
方法说明
setBody(String body)
设置消息体。
setHeaders(Map<String,String> headers)
设置最终返回的Http响应头。
setStatusCode(int statusCode)
设置Http状态码。
setBase64Encoded(boolean isBase64Encoded)
设置body是否经过base64编码。
setBase64EncodedBody(String body)
将输入进行base64编码,并设置到Body中。
addHeader(String key, String value)
增加一组Http header。
removeHeader(String key)
从现有的header中移除指定header。
addHeaders(Map<String,String> headers)
增加多个header。
说明:
APIGTriggerResponse有headers属性,可以通过setHeaders方法和带有headers参数的构造函数对齐进行初始化。
- APIGTriggerEvent相关方法说明
- DIS触发器相关方法说明
表6 DISTriggerEvent相关方法说明 方法名
方法说明
getShardID()
获取分区ID。
getMessage()
获取DIS消息体。(DISMessage结构)
getTag()
获取函数版本。
getStreamName()
获取通道名称。
表7 DISMessage相关方法说明 方法名
方法说明
getNextPatitionCursor()
获取下一个游标。
getRecords()
获取消息记录。(DISRecord结构)
getMillisBehindLatest()
保留方法(目前返回0)。
- DMS触发器相关方法说明
表9 DMSTriggerEvent相关方法说明 方法名
方法说明
getQueueId()
获取队列ID。
getRegion()
获取区域名称。
getEventType()
获取事件类型。(返回“MessageCreated”)
getConsumerGroupId()
获取消费组ID。
getMessages()
获取DMS消息。(DMSMessage结构)
- SMN触发器相关方法说明
表11 SMNTriggerEvent相关方法说明 方法名
方法说明
getRecord()
获取消息记录集合。(SMNRecord结构)
表12 SMNRecord相关方法说明 方法名
方法说明
getEventVersion()
获取事件版本。(当前为1.0)
getEventSubscriptionUrn()
获取订阅URN。
getEventSource()
获取事件源。
getSmn()
获取SMN事件消息体。(SMNBody结构)
- 定时触发器相关方法说明
表14 TimerTriggerEvent相关方法说明 方法名
方法说明
getVersion()
获取版本名称。(当前为“v1.0”)
getTime()
获取当前时间。
getTriggerType()
获取触发器类型。(“Timer”)
getTriggerName()
获取触发器名称。
getUserEvent()
获取触发器附加信息。
- Kafka触发器相关方法说明
表15 Kafka触发器相关方法说明 方法名
方法说明
getEventVersion
获取事件版本。
getRegion
获取地区。
getEventTime
获取产生时间。
getTriggerType
获取触发器类型。
getInstanceId
获取实例ID。
getRecords
获取记录体。
说明:
- 例如使用APIG触发器时,只需要把入口函数(假如函数名为handler)的第一个参数按照如下方式设置:handler(APIGTriggerEvent event, Context context)。
- 关于所有TriggerEvent,上面提到的TriggerEvent方法均有与之对应的set方法,建议在本地调试时使用;DIS和LTS均有对应的getRawData()方法,但无与之相应的setRawData()方法。
- APIG触发器相关方法说明
- Context接口
Context接口提供函数获取函数执行上下文,例如,用户委托的AccessKey/SecretKey、当前请求ID、函数执行分配的内存空间、CPU数等。
Context接口说明如表16所示。
表16 Context类上下文方法说明 方法名
方法说明
getRequestID( )
获取请求ID。
getRemainingTimeInMilliSeconds ( )
获取函数剩余运行时间。
getAccessKey( )
获取用户委托的AccessKey(有效期24小时),使用该方法需要给函数配置委托。
当前函数工作流已停止维护Runtime SDK 中getAccessKey接口,您将无法使用getAccessKey获取临时AK。
getSecretKey( )
获取用户委托的SecretKey(有效期24小时),使用该方法需要给函数配置委托。
当前函数工作流已停止维护Runtime SDK 中getSecretKey接口,您将无法使用getSecretKey获取临时SK。
getSecurityAccessKey( )
获取用户委托的SecurityAccessKey(有效期24小时),使用该方法需要给函数配置委托。
getSecuritySecretKey( )
获取用户委托的SecuritySecretKey(有效期24小时),使用该方法需要给函数配置委托。
getSecurityToken( )
获取用户委托的SecurityToken(有效期24小时),使用该方法需要给函数配置委托。
getUserData(string key)
通过key获取用户通过环境变量传入的值。
getFunctionName( )
获取函数名称。
getRunningTimeInSeconds ( )
获取函数超时时间。
getVersion( )
获取函数的版本。
getMemorySize( )
分配的内存。
getCPUNumber( )
获取函数占用的CPU资源。
getPackage( )
获取函数组。
getToken( )
获取用户委托的token(有效期24小时),使用该方法需要给函数配置委托。
getLogger( )
获取context提供的logger方法(默认会输出时间、请求ID等信息)。
getAlias
获取函数的别名
- 日志接口
Java SDK日志接口日志说明如表17所示。