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

temporalio / sdk-java / #316

13 Sep 2024 05:01PM UTC coverage: 77.963% (+0.3%) from 77.673%
#316

push

github

web-flow
Test server support for async Nexus operations (#2198)

* Test server support for async Nexus operations

* Refactor cancel states

* tests and fixes

* refactor retry logic

* failure handling

* tests

* task timeout

* tests

* feedback

* license

* typo

325 of 381 new or added lines in 7 files covered. (85.3%)

34 existing lines in 8 files now uncovered.

20689 of 26537 relevant lines covered (77.96%)

0.78 hits per line

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

87.1
/temporal-sdk/src/main/java/io/temporal/common/converter/PayloadAndFailureDataConverter.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 static java.nio.charset.StandardCharsets.UTF_8;
24

25
import com.google.common.base.Defaults;
26
import com.google.common.base.Preconditions;
27
import io.temporal.api.common.v1.Payload;
28
import io.temporal.api.common.v1.Payloads;
29
import io.temporal.api.failure.v1.Failure;
30
import io.temporal.failure.DefaultFailureConverter;
31
import io.temporal.failure.TemporalFailure;
32
import io.temporal.payload.context.SerializationContext;
33
import java.lang.reflect.Type;
34
import java.util.*;
35
import javax.annotation.Nonnull;
36
import javax.annotation.Nullable;
37

38
class PayloadAndFailureDataConverter implements DataConverter {
39
  // TODO we should make these fields final and make this DataConverter immutable
40
  //  For that we need to deprecate currently mutating methods like
41
  //  DefaultDataConverter#withPayloadConverterOverrides and
42
  // DefaultDataConverter#withFailureConverter
43
  volatile List<PayloadConverter> converters;
44
  volatile Map<String, PayloadConverter> convertersMap;
45
  volatile FailureConverter failureConverter;
46
  private final @Nullable SerializationContext serializationContext;
47

48
  public PayloadAndFailureDataConverter(@Nonnull List<PayloadConverter> converters) {
49
    this(
1✔
50
        Collections.unmodifiableList(converters),
1✔
51
        createConvertersMap(converters),
1✔
52
        new DefaultFailureConverter(),
53
        null);
54
  }
1✔
55

56
  PayloadAndFailureDataConverter(
57
      @Nonnull List<PayloadConverter> converters,
58
      @Nonnull Map<String, PayloadConverter> convertersMap,
59
      @Nonnull FailureConverter failureConverter,
60
      @Nullable SerializationContext serializationContext) {
1✔
61
    this.failureConverter = Preconditions.checkNotNull(failureConverter, "failureConverter");
1✔
62
    this.converters = Preconditions.checkNotNull(converters, "converters");
1✔
63
    this.convertersMap = Preconditions.checkNotNull(convertersMap, "converterMap");
1✔
64
    this.serializationContext = serializationContext;
1✔
65
  }
1✔
66

67
  @Override
68
  public <T> Optional<Payload> toPayload(T value) throws DataConverterException {
69
    for (PayloadConverter converter : converters) {
1✔
70
      Optional<Payload> result =
71
          (serializationContext != null ? converter.withContext(serializationContext) : converter)
1✔
72
              .toData(value);
1✔
73
      if (result.isPresent()) {
1✔
74
        return result;
1✔
75
      }
76
    }
1✔
77
    throw new DataConverterException(
×
78
        "No PayloadConverter is registered with this DataConverter that accepts value:" + value);
79
  }
80

81
  @Override
82
  public <T> T fromPayload(Payload payload, Class<T> valueClass, Type valueType)
83
      throws DataConverterException {
84
    try {
85
      String encoding =
1✔
86
          payload.getMetadataOrThrow(EncodingKeys.METADATA_ENCODING_KEY).toString(UTF_8);
1✔
87
      PayloadConverter converter = convertersMap.get(encoding);
1✔
88
      if (converter == null) {
1✔
89
        throw new DataConverterException(
×
90
            "No PayloadConverter is registered for an encoding: " + encoding);
91
      }
92
      return (serializationContext != null
1✔
93
              ? converter.withContext(serializationContext)
1✔
94
              : converter)
1✔
95
          .fromData(payload, valueClass, valueType);
1✔
96
    } catch (DataConverterException e) {
1✔
97
      throw e;
1✔
UNCOV
98
    } catch (Exception e) {
×
UNCOV
99
      throw new DataConverterException(payload, valueClass, e);
×
100
    }
101
  }
102

103
  @Override
104
  public Optional<Payloads> toPayloads(Object... values) throws DataConverterException {
105
    if (values == null || values.length == 0) {
1✔
106
      return Optional.empty();
1✔
107
    }
108
    try {
109
      Payloads.Builder result = Payloads.newBuilder();
1✔
110
      for (Object value : values) {
1✔
111
        result.addPayloads(toPayload(value).get());
1✔
112
      }
113
      return Optional.of(result.build());
1✔
114
    } catch (DataConverterException e) {
×
115
      throw e;
×
116
    } catch (Throwable e) {
×
117
      throw new DataConverterException(e);
×
118
    }
119
  }
120

121
  @Override
122
  public <T> T fromPayloads(
123
      int index, Optional<Payloads> content, Class<T> parameterType, Type genericParameterType)
124
      throws DataConverterException {
125
    if (!content.isPresent()) {
1✔
126
      return Defaults.defaultValue(parameterType);
1✔
127
    }
128
    int count = content.get().getPayloadsCount();
1✔
129
    // To make adding arguments a backwards compatible change
130
    if (index >= count) {
1✔
131
      return Defaults.defaultValue(parameterType);
1✔
132
    }
133
    return fromPayload(content.get().getPayloads(index), parameterType, genericParameterType);
1✔
134
  }
135

136
  @Override
137
  @Nonnull
138
  public TemporalFailure failureToException(@Nonnull Failure failure) {
139
    Preconditions.checkNotNull(failure, "failure");
1✔
140
    return (serializationContext != null
1✔
141
            ? failureConverter.withContext(serializationContext)
1✔
142
            : failureConverter)
1✔
143
        .failureToException(failure, this);
1✔
144
  }
145

146
  @Override
147
  @Nonnull
148
  public Failure exceptionToFailure(@Nonnull Throwable throwable) {
149
    Preconditions.checkNotNull(throwable, "throwable");
1✔
150
    return (serializationContext != null
1✔
151
            ? failureConverter.withContext(serializationContext)
1✔
152
            : failureConverter)
1✔
153
        .exceptionToFailure(throwable, this);
1✔
154
  }
155

156
  @Override
157
  public @Nonnull DataConverter withContext(@Nonnull SerializationContext context) {
158
    return new PayloadAndFailureDataConverter(converters, convertersMap, failureConverter, context);
1✔
159
  }
160

161
  static Map<String, PayloadConverter> createConvertersMap(List<PayloadConverter> converters) {
162
    Map<String, PayloadConverter> newConverterMap = new HashMap<>();
1✔
163
    for (PayloadConverter converter : converters) {
1✔
164
      newConverterMap.put(converter.getEncodingType(), converter);
1✔
165
    }
1✔
166
    return newConverterMap;
1✔
167
  }
168
}
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