3

Google flexible app engine spring boot project running on local with datastore is giving the com.google.cloud.datastore.DatastoreException Unauthenticated exception while saving entity.

{
   "timestamp": 1512077140003,
   "status": 500,
   "error": "Internal Server Error",
   "exception": "com.google.cloud.datastore.DatastoreException",
   "message": "Unauthenticated.",
   "path": "/users"
}

The error description here says the request header does not have valid authentication header, But where to place the auth header does not mentioned.

anybody faced same kind of situation?

Aniruddha Das
  • 20,520
  • 23
  • 96
  • 132

2 Answers2

7

Canonical Error Code: UNAUTHENTICATED

Description: The com.google.cloud.datastore.DatastoreException simply indicates that the request did not have valid authentication credentials.

Recommended Action: Do not retry without fixing the problem. In this case, you need to check the login credentials again.

More read can be found on this page https://cloud.google.com/datastore/docs/concepts/errors#error_codes

Solution:

Simply you have to run gcloud beta auth application-default login. But I spent a half of a day until found it there. I thought it should be enough to gcloud init. As an alternative, you can use google authentication via Google OAuth2 but that is the hard way.

Amar Prakash Pandey
  • 1,278
  • 18
  • 23
  • After running this command, I'm getting a different error now: `com.google.datastore.v1.client.DatastoreException: Permission denied on resource project no_app_id., code=PERMISSION_DENIED`. When I do `gcloud init` I can see that my project id is set. Any idea how to set the project id correctly when testing on local? – DFB Jun 29 '22 at 15:55
0

I ended up going in another direction.

  1. You can authenticate and use a remote Datastore, like Amar mentioned;
  2. You can also get credentials, store it locally, reference it in your application.properties using the spring.cloud.gcp.datastore.credentials.location=file://FULL_PATH_TO_THE_CREDENTIALS_FILE and still use a remote Datastore;
  3. But my favorite option is to run it full local using a Datastore emulator, so no authentication is needed at all:

src/test/resources/application.properties

    # if it exists, comment out or delete the following property:
    # spring.cloud.gcp.datastore.credentials.location

    # add the following
    spring.cloud.gcp.emulator-enabled=true

    # if you're not using environment variables, make sure the following property exists
    spring.cloud.gcp.project-id=your-project-id

Be aware that if your running integration tests, or mixing remote and local tests, you might need different .properties files for each test.

Your test class

    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    private static LocalDatastoreHelper helper;

    @BeforeClass
    public static void setUpClass() throws IOException, InterruptedException {
        logger.info("[Datastore-Emulator] start");
        helper = LocalDatastoreHelper.create();
        helper.start();
        logger.info("[Datastore-Emulator] listening on port {}", helper.getPort());

        System.setProperty(DatastoreHelper.LOCAL_HOST_ENV_VAR, "localhost:" + helper.getPort());
    }

    @AfterClass
    public static void cleanUpClass() throws InterruptedException, TimeoutException, IOException {
        logger.info("[Datastore-Emulator] stop");
        helper.stop();
    }

    @Before
    public void init() throws IOException {
        logger.info("[Datastore-Emulator] cleaning data");
        helper.reset();
    }

This approach works great for Repositories (org.springframework.cloud.gcp.data.datastore.repository.DatastoreRepository), but if you want to use a Datastore directly, you can check this.

Refs

Renato Back
  • 706
  • 1
  • 10
  • 21