首页 > 解决方案 > 通过 Java API 创建 Google Cloud Function:“io.grpc.StatusRuntimeException: INVALID_ARGUMENT”

问题描述

我正在尝试使用带有此客户端的 Java 客户端 API 创建一个谷歌云函数:

Credentials myCredentials = ServiceAccountCredentials.fromStream(new FileInputStream(keyFile));
CloudFunctionsServiceSettings settings = CloudFunctionsServiceSettings.newBuilder()
        .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials)).build();
client = CloudFunctionsServiceClient.create(settings);


String project = "my-project-name";
String location = "us-central1";

LocationName locationName = LocationName.of( project, location );
CloudFunction function = CloudFunction.newBuilder().build();
CloudFunction response = client.createFunctionAsync(locationName, function).get();

我尝试了不同的调用,但我总是得到以下堆栈跟踪:

java.util.concurrent.ExecutionException: com.google.api.gax.rpc.InvalidArgumentException: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: The request has errors
        at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:566)
        at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:547)
        at com.google.common.util.concurrent.FluentFuture$TrustedFuture.get(FluentFuture.java:86)
        at com.google.common.util.concurrent.ForwardingFuture.get(ForwardingFuture.java:62)
        at com.google.api.gax.longrunning.OperationFutureImpl.get(OperationFutureImpl.java:127)
        at it.myapp.test.App.main(App.java:59)
Caused by: com.google.api.gax.rpc.InvalidArgumentException: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: The request has errors
        at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:49)
        at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:72)
        at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:60)
        at com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:97)
        at com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:68)
        at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1041)
        at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:30)
        at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1215)
        at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:983)
        at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:771)
        at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:563)
        at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:533)
        at io.grpc.internal.DelayedClientCall$DelayedListener$3.run(DelayedClientCall.java:464)
        at io.grpc.internal.DelayedClientCall$DelayedListener.delayOrExecute(DelayedClientCall.java:428)
        at io.grpc.internal.DelayedClientCall$DelayedListener.onClose(DelayedClientCall.java:461)
        at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:553)
        at io.grpc.internal.ClientCallImpl.access$300(ClientCallImpl.java:68)
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:739)
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:718)
        at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
        at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: The request has errors
        at io.grpc.Status.asRuntimeException(Status.java:535)
        ... 16 more

我的 pom.xml 有以下设置:

<dependencyManagement>
<dependencies>
  <dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-functions-bom</artifactId>
    <version>1.0.8</version>
    <type>pom</type>
    <scope>import</scope>
  </dependency>
</dependencies>
</dependencyManagement>
<dependencies>
 <dependency>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-functions</artifactId>
 </dependency>
</dependencies>

有谁知道我做错了什么?

谢谢

标签: javagoogle-cloud-platformgoogle-cloud-functions

解决方案


The error means that your Function Builder is missing the required parameters in order to create the function. If you try to create a function via Cloud Console, you're required to enter details such as function name, entrypoint, runtime, trigger type, and source code.

I've already reached out to the engineers and they are now informed with regards to the lack of details in the log output.

As a solution, here's a sample code that will create a Cloud Function running on Java 11. Of course you can always choose any type of runtime you want:

package function;

import com.google.cloud.functions.v1.CloudFunctionsServiceClient;
import com.google.cloud.functions.v1.HttpsTrigger;
import com.google.cloud.functions.v1.CloudFunction;
import com.google.cloud.functions.v1.LocationName;

public class App {
  public static void main( String[] args ){
    try {

      // TODO: Add your credentials here

      CloudFunctionsServiceClient cloudFunctionsServiceClient = CloudFunctionsServiceClient.create();
      String location = LocationName.of("[PROJECT_ID]", "us-central1").toString();
      CloudFunction function = CloudFunction.newBuilder()
        .setName(location + "/functions/[FUNCTION_NAME]")
        .setEntryPoint("functions.HelloHttp") // fully qualified class name (FQN)
        .setRuntime("java11")
        .setHttpsTrigger(HttpsTrigger.getDefaultInstance())
        .setSourceArchiveUrl("gs://[BUCKET_NAME]/source_code.zip")
        .build(); 
  
      CloudFunction response = cloudFunctionsServiceClient.createFunctionAsync(location, function).get();
    }catch (Exception e){
      e.printStackTrace();
    }
  }
}

Note: If your zipped source code is from a storage bucket, make sure your source files are at the root of the ZIP file, rather than a folder containing the files.


推荐阅读