Skip to content
Open
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
02fadd7
extended knative custom functions to support headers and query params
oEscal May 16, 2025
515c491
code for returning REST custom function headers, status code, and to …
oEscal May 23, 2025
153b334
Merge branch 'main' into feature/3936
oEscal May 23, 2025
f05f97b
Merge branch 'feature/knative-headers' into feature/3938
oEscal May 23, 2025
f045a43
code for returning Knative custom function headers, status code, and …
oEscal May 23, 2025
7a5ae12
Merge branch 'main' into feature/knative-headers
oEscal May 26, 2025
ebde233
added the header and query arguments feature in knative for POSTs as …
oEscal May 28, 2025
c1f4e7a
small fix on the AbstractParamsDecorator
oEscal May 29, 2025
b09d8ff
Merge branch 'main' into feature/3938
oEscal May 29, 2025
c0d0fa2
Merge branch 'feature/3936' into feature/3938
oEscal May 29, 2025
0bba1b5
merge updates
oEscal May 29, 2025
f981ecd
Merge branch 'main' into feature/knative-headers
oEscal May 29, 2025
61e5ecb
Merge branch 'main' into feature/3936
oEscal May 29, 2025
1728867
fixed style
oEscal May 29, 2025
c746a4e
Merge branch 'feature/3936' into feature/3938
oEscal May 29, 2025
08ff33d
fixed style
oEscal May 29, 2025
f340c45
FAIL_ON_STATUS_ERROR_PARAMETER_NAME default for knative
oEscal May 29, 2025
0d27227
fixed failing tests and format
oEscal May 29, 2025
a2eb1a4
Merge branch 'feature/knative-headers' into feature/3938
oEscal May 29, 2025
8d90e4b
fixed OperationTests and format
oEscal May 29, 2025
033521a
small fix for the tests
oEscal May 30, 2025
db2e0e7
formatting
oEscal May 30, 2025
7fbc99b
Merge branch 'feature/knative-headers' into feature/3938
oEscal Jun 2, 2025
736dd68
Merge branch 'main' into feature/3938
oEscal Jun 2, 2025
d75081a
small fix
oEscal Jun 3, 2025
ec21e7b
fix extractJsonNodeValue
oEscal Sep 9, 2025
a0374d9
small fix because of states that share the same execution scope (e.g.…
oEscal Sep 12, 2025
c05d384
merge with main
oEscal Sep 15, 2025
3ded6c6
formatting issues
oEscal Sep 15, 2025
ad6c659
fixed checkStatusCode() call to still work with .statusCode
oEscal Sep 15, 2025
36cc08d
fix RestWorkItemHandlerTest.java
oEscal Sep 15, 2025
f13a9e6
unit tests
oEscal Sep 17, 2025
8c9f038
merge with pr 3937
oEscal Sep 18, 2025
bdb5419
Merge branch 'apache:main' into feature/3936
oEscal Sep 18, 2025
8d65650
Merge branch 'apache:main' into feature/3938
oEscal Sep 18, 2025
b5e6832
some of the reviewer requests
oEscal Sep 29, 2025
4da423e
requested restructure
oEscal Oct 14, 2025
ad843d2
answer the reviewers comments and IT test
oEscal Oct 17, 2025
f60f723
Update kogito-serverless-workflow/kogito-serverless-workflow-rest-run…
oEscal Oct 20, 2025
bced3b3
Merge branch 'main' into feature/3938
oEscal Oct 21, 2025
d476723
Merge branch 'feature/3936' into feature/3938
oEscal Oct 21, 2025
c0fdab3
going to the previous code version and updating the knative result ha…
oEscal Oct 27, 2025
cda741f
going back to defining headers and query params
oEscal Oct 27, 2025
70e17f0
Merge branch 'apache:main' into feature/3938
oEscal Mar 13, 2026
6bf4218
Change header and query prefix back to private access
oEscal Mar 14, 2026
481b736
improve PlainJsonKnativeParamsDecorator implementation
oEscal Mar 17, 2026
8d9b8b2
Merge branch 'apache:main' into feature/3938
oEscal Mar 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
*/
package org.kogito.workitem.rest.decorators;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.kie.kogito.internal.process.workitem.KogitoWorkItem;

Expand All @@ -30,26 +32,36 @@ public abstract class AbstractParamsDecorator implements ParamsDecorator {

@Override
public void decorate(KogitoWorkItem item, Map<String, Object> parameters, HttpRequest<?> request) {
extractHeadersQueries(item, parameters, request);
}

protected String toHeaderKey(String key) {
return key;
}

protected String toQueryKey(String key) {
return key;
}

protected Set<String> extractHeadersQueries(KogitoWorkItem item, Map<String, Object> parameters, HttpRequest<?> request) {
Set<String> consideredParams = new HashSet<>();

Iterator<Entry<String, Object>> iter = parameters.entrySet().iterator();
while (iter.hasNext()) {
Entry<String, Object> entry = iter.next();
String key = entry.getKey();
if (isHeaderParameter(key)) {
request.putHeader(toHeaderKey(key), entry.getValue().toString());
consideredParams.add(key);
iter.remove();
} else if (isQueryParameter(key)) {
request.addQueryParam(toQueryKey(key), entry.getValue().toString());
consideredParams.add(key);
iter.remove();
}
}
}

protected String toHeaderKey(String key) {
return key;
}

protected String toQueryKey(String key) {
return key;
return consideredParams;
}

protected abstract boolean isHeaderParameter(String key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.kie.kogito.serverless.workflow.parser.ParserContext;
import org.kie.kogito.serverless.workflow.parser.VariableInfo;
import org.kie.kogito.serverless.workflow.parser.types.WorkItemTypeHandler;
import org.kie.kogito.serverless.workflow.suppliers.JsonNodeResultHandlerSupplier;
import org.kie.kogito.serverless.workflow.suppliers.ParamsRestBodyBuilderSupplier;
import org.kogito.workitem.rest.RestWorkItemHandler;

Expand Down Expand Up @@ -107,6 +108,7 @@ private static List<String> getPayloadFields(FunctionRef functionRef) {
context.getContext(), String.class, DEFAULT_REQUEST_TIMEOUT_VALUE);

return node.workParameter(RestWorkItemHandler.BODY_BUILDER, new ParamsRestBodyBuilderSupplier())
.workParameter(RestWorkItemHandler.RESULT_HANDLER, new JsonNodeResultHandlerSupplier())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to do that?
How is this change related with the issue description?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was a leftover from the previous implementation where I was not considering the $WORKFLOW variable yet. However, this should be added to the Knative custom function to give control to the developer over the status code, message, and headers. What do you think? Do I create another issue/PR for that?

.workParameter(RestWorkItemHandler.REQUEST_TIMEOUT_IN_MILLIS, requestTimeout)
.metaData(TaskDescriptor.KEY_WORKITEM_TYPE, RestWorkItemHandler.REST_TASK_TYPE)
.workName(KnativeWorkItemHandler.NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,25 @@
*/
package org.kie.kogito.addons.quarkus.knative.serving.customfunctions;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.kie.kogito.event.cloudevents.utils.CloudEventUtils;
import org.kie.kogito.internal.process.workitem.KogitoWorkItem;
import org.kogito.workitem.rest.decorators.PrefixParamsDecorator;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import io.vertx.mutiny.ext.web.client.HttpRequest;

import static org.kie.kogito.addons.quarkus.knative.serving.customfunctions.KnativeWorkItemHandler.CLOUDEVENT_SENT_AS_PLAIN_JSON_ERROR_MESSAGE;
import static org.kie.kogito.addons.quarkus.knative.serving.customfunctions.KnativeWorkItemHandler.ID;
import static org.kie.kogito.serverless.workflow.SWFConstants.MODEL_WORKFLOW_VAR;

public final class PlainJsonKnativeParamsDecorator extends PrefixParamsDecorator {

Expand All @@ -37,12 +45,44 @@ public void decorate(KogitoWorkItem workItem, Map<String, Object> parameters, Ht
if (isCloudEvent(KnativeFunctionPayloadSupplier.getPayload(parameters))) {
throw new IllegalArgumentException(CLOUDEVENT_SENT_AS_PLAIN_JSON_ERROR_MESSAGE);
}

super.decorate(workItem, parameters, request);
buildFromParams(workItem, parameters, request);
}

private static boolean isCloudEvent(Map<String, Object> payload) {
List<String> cloudEventMissingAttributes = CloudEventUtils.getMissingAttributes(payload);
return !payload.isEmpty() && (cloudEventMissingAttributes.isEmpty() || (cloudEventMissingAttributes.size() == 1 && cloudEventMissingAttributes.contains(ID)));
}

private void buildFromParams(KogitoWorkItem workItem, Map<String, Object> parameters, HttpRequest<?> request) {
Map<String, Object> inputModel = new HashMap<>();

Object inputModelObject = parameters.get(MODEL_WORKFLOW_VAR);

ObjectNode inputModelCopy = null;
if (inputModelObject instanceof ObjectNode objectNode) {
ObjectMapper mapper = new ObjectMapper();
objectNode.fields().forEachRemaining(entry -> {
JsonNode value = entry.getValue();
Object rawValue = mapper.convertValue(value, Object.class);
inputModel.put(entry.getKey(), rawValue);
});

try {
inputModelCopy = (ObjectNode) mapper.readTree(objectNode.toString());
} catch (JsonProcessingException e) {
throw new RuntimeException("Failed to copy MODEL_WORKFLOW_VAR", e);
}
}

Set<String> paramsRemove = super.extractHeadersQueries(workItem, inputModel, request);
super.decorate(workItem, parameters, request);

if (inputModelCopy != null) {
// mutate the safe copy
inputModelCopy.remove(paramsRemove);

// replace the original entry in parameters with the copy
parameters.put(MODEL_WORKFLOW_VAR, inputModelCopy);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im unable to understand the purpose of this code.
Why do you need to remove properties from the model?
Why can you extract the header parameters directly from the original?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too confusing.
Basically extradHeadersQueries is called twice over the same request, one withe parameters, one with the model, why?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented this a long time ago. But from what I remember, this was to avoid sending the headers and queries from the params (HEADER_* and QUERY_*) as arguments to the service when they are already processed as headers and queries. But yes, I agree with you; this is too confusing at the moment. I will find another way of doing this more cleanly.

}
}
Loading