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

temporalio / sdk-java / #181

pending completion
#181

push

github-actions

web-flow
Properly wrap exceptions from schedule client (#1827)

Wrap schedule exception

37 of 37 new or added lines in 1 file covered. (100.0%)

18557 of 23894 relevant lines covered (77.66%)

0.78 hits per line

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

57.69
/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 com.google.common.base.Preconditions;
26
import io.temporal.api.common.v1.Payload;
27
import io.temporal.api.common.v1.Payloads;
28
import io.temporal.api.failure.v1.Failure;
29
import io.temporal.common.Experimental;
30
import io.temporal.failure.DefaultFailureConverter;
31
import io.temporal.failure.TemporalFailure;
32
import io.temporal.payload.codec.PayloadCodec;
33
import io.temporal.payload.context.SerializationContext;
34
import java.lang.reflect.Type;
35
import java.util.Arrays;
36
import java.util.Optional;
37
import javax.annotation.Nonnull;
38

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

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

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

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

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

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

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

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

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

184
  /**
185
   * Serialize an existing Throwable object into a Failure object. The default implementation
186
   * delegates the conversion process to an instance of {@link FailureConverter}, using this data
187
   * converter for payload encoding.
188
   *
189
   * @param throwable a Throwable object to serialize into a Failure protobuf object
190
   * @throws NullPointerException if throwable is null
191
   */
192
  @Nonnull
193
  default Failure exceptionToFailure(@Nonnull Throwable throwable) {
194
    Preconditions.checkNotNull(throwable, "throwable");
×
195
    return new DefaultFailureConverter().exceptionToFailure(throwable, this);
×
196
  }
197

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

221
  /**
222
   * @deprecated use {@link DataConverter#fromPayloads(int, Optional, Class, Type)}. This is an SDK
223
   *     implementation detail and never was expected to be exposed to users.
224
   */
225
  @Deprecated
226
  static Object[] arrayFromPayloads(
227
      DataConverter converter,
228
      Optional<Payloads> content,
229
      Class<?>[] parameterTypes,
230
      Type[] genericParameterTypes)
231
      throws DataConverterException {
232
    return converter.fromPayloads(content, parameterTypes, genericParameterTypes);
×
233
  }
234
}
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

© 2025 Coveralls, Inc