aboutsummaryrefslogtreecommitdiffstats
path: root/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeRequestData.java
blob: 58dfa1bdcd5270b6b58b8fbbc7cad2de0e48e5a6 (plain) (blame)
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.protocol;

import com.yahoo.jrt.Request;
import com.yahoo.slime.Cursor;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.Slime;
import com.yahoo.slime.SlimeUtils;
import com.yahoo.vespa.config.ConfigKey;
import com.yahoo.vespa.config.PayloadChecksum;
import com.yahoo.vespa.config.PayloadChecksums;
import com.yahoo.vespa.config.util.ConfigUtils;

import java.util.Optional;

import static com.yahoo.vespa.config.PayloadChecksum.Type.MD5;
import static com.yahoo.vespa.config.PayloadChecksum.Type.XXHASH64;

/**
 * Contains slime request data objects. Provides methods for reading various fields from slime request data.
 * All data is read lazily.
 *
* @author Ulf Lilleengen
*/
class SlimeRequestData {

    private static final String REQUEST_VERSION = "version";
    private static final String REQUEST_DEF_NAME = "defName";
    private static final String REQUEST_DEF_NAMESPACE = "defNamespace";
    private static final String REQUEST_DEF_CONTENT = "defContent";
    private static final String REQUEST_CLIENT_CONFIGID = "configId";
    private static final String REQUEST_CLIENT_HOSTNAME = "clientHostname";
    private static final String REQUEST_CURRENT_GENERATION = "currentGeneration";
    private static final String REQUEST_CONFIG_MD5 = "configMD5";
    private static final String REQUEST_CONFIG_XXHASH64 = "configXxhash64";
    private static final String REQUEST_TRACE = "trace";
    private static final String REQUEST_TIMEOUT = "timeout";
    private static final String REQUEST_DEF_MD5 = "defMD5";
    private static final String REQUEST_COMPRESSION_TYPE = "compressionType";
    private static final String REQUEST_VESPA_VERSION = "vespaVersion";

    private final Request request;
    private Slime data = null;

    SlimeRequestData(Request request) {
        this.request = request;
    }

    SlimeRequestData(Request request, Slime data) {
        this.request = request;
        this.data = data;
    }

    private Slime getData() {
        if (data == null) {
            data = SlimeUtils.jsonToSlime(request.parameters().get(0).asString());
        }
        return data;
    }

    private Inspector getRequestField(String requestField) {
        return getData().get().field(requestField);
    }

    ConfigKey<?> getConfigKey() {
        return ConfigKey.createFull(getRequestField(REQUEST_DEF_NAME).asString(),
                                    getRequestField(REQUEST_CLIENT_CONFIGID).asString(),
                                    getRequestField(REQUEST_DEF_NAMESPACE).asString());
    }

    DefContent getSchema() {
        Inspector content = getRequestField(REQUEST_DEF_CONTENT);
        return DefContent.fromSlime(content);
    }

    String getClientHostName() {
        return getRequestField(REQUEST_CLIENT_HOSTNAME).asString();
    }

    long getTimeout() {
        return getRequestField(REQUEST_TIMEOUT).asLong();
    }

    String getRequestConfigMd5() { return getRequestField(REQUEST_CONFIG_MD5).asString(); }

    String getRequestDefMd5() { return getRequestField(REQUEST_DEF_MD5).asString(); }

    PayloadChecksum getRequestConfigXxhash64() {
        Inspector xxhash64Field = getRequestField(REQUEST_CONFIG_XXHASH64);
        return xxhash64Field.valid()
                ? new PayloadChecksum(xxhash64Field.asString(), XXHASH64)
                : PayloadChecksum.empty(XXHASH64);
    }

    PayloadChecksums getRequestConfigChecksums() {
        return PayloadChecksums.from(getRequestConfigMd5(), getRequestConfigXxhash64().asString());
    }

    long getRequestGeneration() {
        return getRequestField(REQUEST_CURRENT_GENERATION).asLong();
    }

    static Slime encodeRequest(ConfigKey<?> key,
                               String hostname,
                               DefContent defSchema,
                               PayloadChecksums payloadChecksums,
                               long generation,
                               long timeout,
                               Trace trace,
                               long protocolVersion,
                               CompressionType compressionType,
                               Optional<VespaVersion> vespaVersion) {
        Slime data = new Slime();
        Cursor request = data.setObject();
        request.setLong(REQUEST_VERSION, protocolVersion);
        request.setString(REQUEST_DEF_NAME, key.getName());
        request.setString(REQUEST_DEF_NAMESPACE, key.getNamespace());
        request.setString(REQUEST_DEF_MD5, ConfigUtils.getDefMd5(defSchema.asList()));
        request.setString(REQUEST_CLIENT_CONFIGID, key.getConfigId());
        request.setString(REQUEST_CLIENT_HOSTNAME, hostname);
        defSchema.serialize(request.setArray(REQUEST_DEF_CONTENT));
        if (payloadChecksums.getForType(XXHASH64) != null)
            request.setString(REQUEST_CONFIG_XXHASH64, payloadChecksums.getForType(XXHASH64).asString());
        if (payloadChecksums.getForType(MD5) != null)
            request.setString(REQUEST_CONFIG_MD5, payloadChecksums.getForType(MD5).asString());
        request.setLong(REQUEST_CURRENT_GENERATION, generation);
        request.setLong(REQUEST_TIMEOUT, timeout);
        request.setString(REQUEST_COMPRESSION_TYPE, compressionType.name());
        vespaVersion.ifPresent(version -> request.setString(REQUEST_VESPA_VERSION, version.toString()));
        trace.serialize(request.setObject(REQUEST_TRACE));
        return data;
    }

    Trace getRequestTrace() {
        return Trace.fromSlime(getRequestField(REQUEST_TRACE));
    }

    public CompressionType getCompressionType() {
        Inspector field = getRequestField(REQUEST_COMPRESSION_TYPE);
        return field.valid() ? CompressionType.parse(field.asString()) : CompressionType.UNCOMPRESSED;
    }

    public Optional<VespaVersion> getVespaVersion() {
        String versionString = getRequestField(REQUEST_VESPA_VERSION).asString(); // will be "" if not set, never null
        return versionString.isEmpty() ? Optional.empty() : Optional.of(VespaVersion.fromString(versionString));
    }

}