• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

temporalio / sdk-java / #168

pending completion
#168

push

github-actions

web-flow
Data Converters now have method deserializing all the Payloads at once (#1726)

Issue #1345

16 of 16 new or added lines in 6 files covered. (100.0%)

17113 of 20963 relevant lines covered (81.63%)

0.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.18
/temporal-sdk/src/main/java/io/temporal/common/converter/DataConverter.java
1
/*
2
 * Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
3
 *
4
 * Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5
 *
6
 * Modifications copyright (C) 2017 Uber Technologies, Inc.
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this material except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *   http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20

21
package io.temporal.common.converter;
22

23
import com.fasterxml.jackson.databind.ObjectMapper;
24
import com.google.common.base.Defaults;
25
import io.temporal.api.common.v1.Payload;
26
import io.temporal.api.common.v1.Payloads;
27
import io.temporal.api.failure.v1.Failure;
28
import io.temporal.common.Experimental;
29
import io.temporal.failure.TemporalFailure;
30
import io.temporal.payload.codec.PayloadCodec;
31
import io.temporal.payload.context.SerializationContext;
32
import java.lang.reflect.Type;
33
import java.util.Arrays;
34
import java.util.Optional;
35
import javax.annotation.Nonnull;
36

37
/**
38
 * Used by the framework to serialize/deserialize method parameters that need to be sent over the
39
 * wire.
40
 *
41
 * <h2>Most users should never implement this interface until absolutely needed.</h2>
42
 *
43
 * Instead, users should implement
44
 *
45
 * <ul>
46
 *   <li>{@link PayloadConverter} to customize Object &lt;-&gt; Payload (bytes) conversion
47
 *   <li>{@link PayloadCodec} to perform Payload (bytes) &lt;-&gt; Payload (bytes) encoding (like
48
 *       encryption or compression)
49
 * </ul>
50
 *
51
 * A custom {@link PayloadConverter} can be registered on {@link DefaultDataConverter} instance. For
52
 * that:
53
 *
54
 * <ul>
55
 *   <li>Obtain {@link DefaultDataConverter} instance from {@link
56
 *       DefaultDataConverter#newDefaultInstance()}. Register your custom {@link PayloadConverter}
57
 *       using {@link DefaultDataConverter#withPayloadConverterOverrides(PayloadConverter...)}. This
58
 *       way will preserve the standard set of {@link PayloadConverter}s supplied by Temporal
59
 *       JavaSDK other that the ones that were overridden. See {@link
60
 *       DefaultDataConverter#STANDARD_PAYLOAD_CONVERTERS})
61
 *   <li>Pass the custom {@link PayloadConverter} directly to {@link
62
 *       DefaultDataConverter#DefaultDataConverter(PayloadConverter...)} to discard the standard
63
 *       {@link PayloadConverter}s supplied by Temporal JavaSDK out of the box.
64
 * </ul>
65
 *
66
 * A {@link DataConverter} created on previous step may be bundled with {@link PayloadCodec}s using
67
 * {@link CodecDataConverter} or used directly if no custom {@link PayloadCodec}s are needed.
68
 */
69
public interface DataConverter {
70

71
  /**
72
   * @deprecated use {@link GlobalDataConverter#get()}
73
   */
74
  @Deprecated
75
  static DataConverter getDefaultInstance() {
76
    return GlobalDataConverter.get();
×
77
  }
78

79
  /**
80
   * @param value value to convert
81
   * @return a {@link Payload} which is a protobuf message containing byte-array serialized
82
   *     representation of {@code value}. Optional here is for legacy and backward compatibility
83
   *     reasons. This Optional is expected to always be filled.
84
   * @throws DataConverterException if conversion fails
85
   */
86
  <T> Optional<Payload> toPayload(T value) throws DataConverterException;
87

88
  <T> T fromPayload(Payload payload, Class<T> valueClass, Type valueType)
89
      throws DataConverterException;
90

91
  /**
92
   * Implements conversion of a list of values.
93
   *
94
   * @param values Java values to convert to String.
95
   * @return converted value. Return empty Optional if values are empty.
96
   * @throws DataConverterException if conversion of the value passed as parameter failed for any
97
   *     reason.
98
   */
99
  Optional<Payloads> toPayloads(Object... values) throws DataConverterException;
100

101
  /**
102
   * Implements conversion of a single {@link Payload} from the serialized {@link Payloads}.
103
   *
104
   * @param index index of the value in the payloads
105
   * @param content serialized value to convert to Java objects.
106
   * @param valueType type of the value stored in the {@code content}
107
   * @param valueGenericType generic type of the value stored in the {@code content}
108
   * @return converted Java object
109
   * @throws DataConverterException if conversion of the data passed as parameter failed for any
110
   *     reason.
111
   */
112
  <T> T fromPayloads(
113
      int index, Optional<Payloads> content, Class<T> valueType, Type valueGenericType)
114
      throws DataConverterException;
115

116
  /**
117
   * Implements conversion of the whole {@code content} {@link Payloads} into an array of values of
118
   * different types.
119
   *
120
   * <p>Implementation note<br>
121
   * This method is expected to return an array of the same length as {@code parameterTypes}. If
122
   * {@code content} has not enough {@link Payload} elements, this method provides default
123
   * instances.
124
   *
125
   * @param content serialized value to convert to Java objects.
126
   * @param parameterTypes types of the values stored in the @code content}
127
   * @param genericParameterTypes generic types of the values stored in the {@code content}
128
   * @return array if converted Java objects
129
   * @throws DataConverterException if conversion of the data passed as parameter failed for any
130
   *     reason.
131
   */
132
  default Object[] fromPayloads(
133
      Optional<Payloads> content, Class<?>[] parameterTypes, Type[] genericParameterTypes)
134
      throws DataConverterException {
135
    if (parameterTypes != null
1✔
136
        && (genericParameterTypes == null
137
            || parameterTypes.length != genericParameterTypes.length)) {
138
      throw new IllegalArgumentException(
×
139
          "parameterTypes don't match length of valueTypes: "
140
              + Arrays.toString(parameterTypes)
×
141
              + "<>"
142
              + Arrays.toString(genericParameterTypes));
×
143
    }
144

145
    int totalLength = parameterTypes.length;
1✔
146
    Object[] result = new Object[totalLength];
1✔
147
    if (!content.isPresent()) {
1✔
148
      // Return defaults for all the parameters
149
      for (int i = 0; i < parameterTypes.length; i++) {
1✔
150
        result[i] = Defaults.defaultValue((Class<?>) genericParameterTypes[i]);
×
151
      }
152
      return result;
1✔
153
    }
154
    Payloads payloads = content.get();
1✔
155
    int count = payloads.getPayloadsCount();
1✔
156
    for (int i = 0; i < parameterTypes.length; i++) {
1✔
157
      Class<?> pt = parameterTypes[i];
1✔
158
      Type gt = genericParameterTypes[i];
1✔
159
      if (i >= count) {
1✔
160
        result[i] = Defaults.defaultValue((Class<?>) gt);
1✔
161
      } else {
162
        result[i] = this.fromPayload(payloads.getPayloads(i), pt, gt);
1✔
163
      }
164
    }
165
    return result;
1✔
166
  }
167

168
  /**
169
   * Instantiate an appropriate Java Exception from a serialized Failure object. The default
170
   * implementation delegates the conversion process to an instance of {@link FailureConverter},
171
   * using this data converter for payload decoding.
172
   *
173
   * @param failure Failure protobuf object to deserialize into an exception
174
   * @throws NullPointerException if failure is null
175
   */
176
  @Nonnull
177
  TemporalFailure failureToException(@Nonnull Failure failure);
178

179
  /**
180
   * Serialize an existing Throwable object into a Failure object. The default implementation
181
   * delegates the conversion process to an instance of {@link FailureConverter}, using this data
182
   * converter for payload encoding.
183
   *
184
   * @param throwable a Throwable object to serialize into a Failure protobuf object
185
   * @throws NullPointerException if throwable is null
186
   */
187
  @Nonnull
188
  Failure exceptionToFailure(@Nonnull Throwable throwable);
189

190
  /**
191
   * A correct implementation of this interface should have a fully functional "contextless"
192
   * implementation. Temporal SDK will call this method when a knowledge of the context exists, but
193
   * {@link DataConverter} can be used directly by user code and sometimes SDK itself without any
194
   * context.
195
   *
196
   * <p>Note: this method is expected to be cheap and fast. Temporal SDK doesn't always cache the
197
   * instances and may be calling this method very often. Users are responsible to make sure that
198
   * this method doesn't recreate expensive objects like Jackson's {@link ObjectMapper} on every
199
   * call.
200
   *
201
   * @param context provides information to the data converter about the abstraction the data
202
   *     belongs to
203
   * @return an instance of DataConverter that may use the provided {@code context} for
204
   *     serialization
205
   * @see SerializationContext
206
   */
207
  @Experimental
208
  @Nonnull
209
  default DataConverter withContext(@Nonnull SerializationContext context) {
210
    return this;
×
211
  }
212

213
  /**
214
   * @deprecated use {@link DataConverter#fromPayloads(int, Optional, Class, Type)}. This is an SDK
215
   *     implementation detail and never was expected to be exposed to users.
216
   */
217
  @Deprecated
218
  static Object[] arrayFromPayloads(
219
      DataConverter converter,
220
      Optional<Payloads> content,
221
      Class<?>[] parameterTypes,
222
      Type[] genericParameterTypes)
223
      throws DataConverterException {
224
    return converter.fromPayloads(content, parameterTypes, genericParameterTypes);
×
225
  }
226
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc