Skip to content

Commit

Permalink
[Fix apache#3728] Fixing number casting issues (apache#3730)
Browse files Browse the repository at this point in the history
  • Loading branch information
fjtirado authored Oct 16, 2024
1 parent f4d543d commit 4d5b927
Show file tree
Hide file tree
Showing 8 changed files with 874 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,38 @@ public Optional<WorkItemTransition> activateWorkItemHandler(KogitoWorkItemManage

protected abstract Object internalExecute(KogitoWorkItem workItem, Map<String, Object> parameters);

protected static <C> C safeCast(Object obj, Class<C> clazz) {
return obj == null || clazz.isAssignableFrom(obj.getClass()) ? clazz.cast(obj) : tryConvert(obj, clazz);
}

private static <C> C tryConvert(Object obj, Class<C> clazz) {
if (Number.class.isAssignableFrom(clazz) && Number.class.isAssignableFrom(obj.getClass())) {
Number number = (Number) obj;
if (Integer.class.isAssignableFrom(clazz)) {
return clazz.cast(number.intValue());
} else if (Long.class.isAssignableFrom(clazz)) {
return clazz.cast(number.longValue());
} else if (Double.class.isAssignableFrom(clazz)) {
return clazz.cast(number.doubleValue());
} else if (Float.class.isAssignableFrom(clazz)) {
return clazz.cast(number.floatValue());
} else if (Short.class.isAssignableFrom(clazz)) {
return clazz.cast(number.shortValue());
} else if (Byte.class.isAssignableFrom(clazz)) {
return clazz.cast(number.byteValue());
} else {
throw new UnsupportedOperationException("Type " + clazz + " is not supported");
}
} else {
throw new ClassCastException("OpenAPI expect type " + clazz + " but argument " + obj + " is of type " + obj.getClass());
}
}

protected static <V> V buildBody(Map<String, Object> params, Class<V> clazz) {
for (Object obj : params.values()) {
if (obj != null && clazz.isAssignableFrom(obj.getClass())) {
logger.trace("Invoking workitemhandler with value {}", obj);
return clazz.cast(obj);
return safeCast(obj, clazz);
}
}
V value = JsonObjectUtils.convertValue(params, clazz);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.kie.kogito.serverless.workflow;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.kie.kogito.serverless.workflow.WorkflowWorkItemHandler.safeCast;

public class WorkflowWorkItemHandlerTest {

@Test
void testSafeCast() {
assertThat(safeCast(4, Long.class)).isInstanceOf(Long.class).isEqualTo(4);
assertThat(safeCast(4L, Integer.class)).isInstanceOf(Integer.class).isEqualTo(4);
assertThat(safeCast(4, Float.class)).isInstanceOf(Float.class).isEqualTo(4);
assertThat(safeCast(4, Double.class)).isInstanceOf(Double.class).isEqualTo(4);
assertThat(safeCast(1.5f, Long.class)).isInstanceOf(Long.class).isEqualTo(1);
assertThat(safeCast(1.5f, Integer.class)).isInstanceOf(Integer.class).isEqualTo(1);
assertThat(safeCast(1.5, Float.class)).isInstanceOf(Float.class).isEqualTo(1.5f);
assertThat(safeCast(1.5f, Double.class)).isInstanceOf(Double.class).isEqualTo(1.5);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import com.github.javaparser.ast.Modifier.Keyword;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.expr.CastExpr;
import com.github.javaparser.ast.expr.ClassExpr;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.NameExpr;
Expand Down Expand Up @@ -108,7 +107,8 @@ private WorkflowHandlerGeneratedFile generateHandler(KogitoBuildContext context,
// Using deprecated args method because it is the only way to make it work across Quarkus main and 2.7
Type param = m.args()[i];
if (annotation != null) {
methodCallExpr.addArgument(new CastExpr(fromClass(param), new MethodCallExpr(parameters, "remove").addArgument(new StringLiteralExpr(annotation.value().asString()))));
methodCallExpr.addArgument(new MethodCallExpr("safeCast").addArgument(new MethodCallExpr(parameters, "remove").addArgument(new StringLiteralExpr(annotation.value().asString())))
.addArgument(new ClassExpr(fromClass(param, false))));
} else {
methodCallExpr.addArgument(new MethodCallExpr("buildBody").addArgument(parameters).addArgument(new ClassExpr(fromClass(param, false))));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ quarkus.kubernetes-client.devservices.enabled=false
# OpenApi client properties, see OperationsMockService, which is mocking these two services
quarkus.rest-client.multiplication.cluster1.url=${multiplication-service-mock.url}
quarkus.rest-client.subtraction.url=${subtraction-service-mock.url}
quarkus.rest-client.petstore_openapi_yaml.url=${petstore-service-mock.url}
quarkus.rest-client.array_yaml.url=${array-service-mock.url}


# OpenApi client properties to access the general purpose external-service, which is mocked by the ExternalServiceMock
quarkus.rest-client.external_service_yaml.url=${external-service-mock.url}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
id: long-call
version: "1.0"
specVersion: 0.8.0
name: Long call
description: Description
start: Long call
functions:
- name: 'getPetById'
operation: 'specs/petstore.openapi.yaml#getPetById'
type: rest
states:
- name: Long call
type: operation
actions:
- name: 'Get Pet By Id'
functionRef:
invoke: sync
refName: getPetById
arguments:
petId: 4
end: true
Loading

0 comments on commit 4d5b927

Please sign in to comment.