Skip to content
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

can't created repository,response request body missing #8187

Closed
firstsaofan opened this issue May 14, 2024 · 4 comments · Fixed by #8201
Closed

can't created repository,response request body missing #8187

firstsaofan opened this issue May 14, 2024 · 4 comments · Fixed by #8201
Labels
8.x Relates to 8.x client version Area: Generator Category: Bug

Comments

@firstsaofan
Copy link

Elastic.Clients.Elasticsearch version:

    <PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.13.12" />

Elasticsearch version:8.13.4

docker compose.yml

version: '3'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.13.4
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
    ports:
      - "9200:9200"
    volumes:
      - ./config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

.NET runtime version:

.Net8

Operating system version:

Ubuntu 20 and Windows10

Description of the problem including expected versus actual behavior:

can’t create repository by code call ES,

I have modified the config.yml file of ES and added path.repo. I can use Postman to test the request for create repository, and everything is normal.

image-20240515003957186

But I use Elastic Clients Elasticsearch method to create RepositoryAsync, but encountered an error message stating that the request body is missing. However, in the SharedFileSystemRepository class, type is set by default. In fact, I only need to pass location, and I am not sure what I am missing.

error info:
Invalid Elasticsearch response built from a unsuccessful (400) low level call on PUT: /_snapshot/my-fs-epository
 Exception: Request failed to execute. Call: Status code 400 from: PUT /_snapshot/my-fs-epository. ServerError: Type: parse_exception Reason: "request body is required"

# Audit trail of this API call:
 - [1] BadResponse: Node: http://localhost:9200/ Took: 00:00:00.8736147
# OriginalException: Elastic.Transport.TransportException: Request failed to execute. Call: Status code 400 from: PUT /_snapshot/my-fs-epository. ServerError: Type: parse_exception Reason: "request body is required"
# Request:

# Response:
{"error":{"root_cause":[{"type":"parse_exception","reason":"request body is required"}],"type":"parse_exception","reason":"request body is required"},"status":400}

Steps to reproduce:

  1. Based on the simple Docker Compose file mentioned above, start the ES example and configure the value of path.repo. (On Windows systems, when mounting, the yml file will be treated as a folder and will prompt you to map the folder to the file. You can use Docker cp to copy the configuration file and then map it. At the same time, you need to keep the jvm.options file. Only mounting the config.yml configuration file will cause errors.)
path:
  repo:
    - /usr/share/elasticsearch/data/backups
    - /usr/share/elasticsearch/data/long_term_backups
docker cp elasticsearch:/usr/share/elasticsearch/config ./config/es/

2.Simple example unit test code:

Debugging, break the breakpoint to line 22, and check the value of res to see the error message

        [Fact]
        public async Task CreateFsRepository_Success33()
        {
            //Provide necessary parameters
            string repoName = "my-fs-epository";
            //fs
            string path = "unitTestLocation";
            //var result = await _esBackupRestore.CreateLocalRepository(repoName, path);
            var fsSettings = new SharedFileSystemRepository()
            {
                Settings = new SharedFileSystemRepositorySettings()
                {
                    Location = path
                }
            };
            //var res2 = await Client.Snapshot.GetRepositoryAsync();//I can get repository created,so client init succeed
            var settings = new ElasticsearchClientSettings();
            //.Authentication(new BasicAuthentication("user", "password"));
            var client = new ElasticsearchClient(settings);
            //var res = await client.Snapshot.CreateRepositoryAsync(fsSettings, new Name(repoName));
            var res = await client.Snapshot.CreateRepositoryAsync(fsSettings, new Name(repoName),
                cf => cf.RequestConfiguration(
                    rc => rc.DisableDirectStreaming())
            );
            if (res.ApiCallDetails.HttpStatusCode.Equals(200))
            {
                //return res.ApiCallDetails.HasSuccessfulStatusCode;
                Assert.True(res.ApiCallDetails.HasSuccessfulStatusCode);
            }
            //Assert.True(true);
            Assert.True(res.ApiCallDetails.HasSuccessfulStatusCode);
        }

image-20240515004849279

Expected behavior

Like Postman, successfully created repository

actual

OriginalException: Elastic.Transport.TransportException: Request failed to execute. Call: Status code 400 from: PUT /_snapshot/my-fs-epository. ServerError: Type: parse_exception Reason: "request body is required"

@firstsaofan firstsaofan added 8.x Relates to 8.x client version Category: Bug labels May 14, 2024
@flobernd
Copy link
Member

Hi @firstsaofan,

thank you for the very detailed bug report 🙂 It seems like there is a bug in the code generator. The Serialize method of the CreateRepositoryRequestDescriptor is empty.

I'll investigate that further and provide a fix soon. Just note that I won't be available next week.

@cguedel
Copy link

cguedel commented May 27, 2024

Any update on this? I've tried numerous ways to create a snapshot repository using the client:

  1. Using a request:
var createRepositoryRequest = new CreateRepositoryRequest("reponame")
{
    Repository = new SharedFileSystemRepository()
    {
        Settings = new SharedFileSystemRepositorySettings
        {
            Location = "/opt/elasticsearch/repo/reponame",
            Readonly = true,
            MaxRestoreBytesPerSec = new ByteSize("40m"),
        }
    },
    Verify = true
};
  1. Using the same method as in the original bug report
  2. Using the CreateRepositoryRequestDescriptor descriptor overload

The first one fails with
Elastic.Transport.TransportException: Request failed to execute. Call: Status code 400 from: PUT /_snapshot/reponame?verify=true. ServerError: Type: action_request_validation_exception Reason: "Validation Failed: 1: type is missing;"

The other report the same error as in the original bug report.

This is the very first thing we tried to do with the new client when migrating from NEST and is currently blocking further progress.

@flobernd
Copy link
Member

@cguedel I was not available the past two weeks, but a partial fix is already pushed to a branch. A little bit more work is required before I can release a fixed package. You can expect that to happen this week.

There currently is no workaround.

@flobernd
Copy link
Member

This is fixed in the latest release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
8.x Relates to 8.x client version Area: Generator Category: Bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants