Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,29 @@ private <T> T deserialize(Response response, Type returnType) {
return null;
}

String contentType = response.header("Content-Type");

// Handle binary data (byte[]) for application/octet-stream
if ("application/octet-stream".equals(contentType) && returnType.equals(byte[].class)) {
if (response.body() == null) {
return null;
}
try {
//noinspection unchecked
return (T) response.body().bytes();
} catch (IOException e) {
throw new ConductorClientException(response.message(),
e,
response.code(),
response.headers().toMultimap());
}
}

String body = bodyAsString(response);
if (body == null || "".equals(body)) {
return null;
}

String contentType = response.header("Content-Type");
if (contentType == null || isJsonMime(contentType)) {
// This is hacky. It's required because Conductor's API is returning raw strings as JSON
if (returnType.equals(String.class)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it part of conductor or orkes API? I don't see these endpoints here https://github.com/conductor-oss/conductor/tree/main/rest/src/main/java/com/netflix/conductor/rest/controllers .
If it is part of orkes API it should go to orkes-client project, from my standpoint

* Copyright 2020 Conductor Authors.
* <p>
* Licensed 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 com.netflix.conductor.client.http;


import org.apache.commons.lang3.Validate;

import com.netflix.conductor.client.http.ConductorClientRequest.Method;

import com.fasterxml.jackson.core.type.TypeReference;

/**
* Client for incoming webhook operations in Conductor
*/
public final class IncomingWebhookClient {

private ConductorClient client;

/** Creates a default incoming webhook client */
public IncomingWebhookClient() {
}

public IncomingWebhookClient(ConductorClient client) {
this.client = client;
}

/**
* Kept only for backwards compatibility
*
* @param rootUri basePath for the ApiClient
*/
@Deprecated
public void setRootURI(String rootUri) {
if (client != null) {
client.shutdown();
}
client = new ConductorClient(rootUri);
}

/**
* Handle incoming webhook with POST method
*
* @param id The webhook ID
* @param payload The webhook payload as string
* @return The response from the webhook handler
*/
public String handleWebhook(String id, String payload) {
Validate.notBlank(id, "Webhook ID cannot be blank");
Validate.notNull(payload, "Payload cannot be null");

ConductorClientRequest.Builder requestBuilder = ConductorClientRequest.builder()
.method(Method.POST)
.path("/webhook/{id}")
.addPathParam("id", id)
.body(payload);

ConductorClientRequest request = requestBuilder.build();

ConductorClientResponse<String> resp = client.execute(request, new TypeReference<>() {
});

return resp.getData();
}

/**
* Handle incoming webhook with GET method (typically for ping/health checks)
*
* @param id The webhook ID
* @return The response from the webhook handler
*/
public String handlePing(String id) {
Validate.notBlank(id, "Webhook ID cannot be blank");

ConductorClientRequest.Builder requestBuilder = ConductorClientRequest.builder()
.method(Method.GET)
.path("/webhook/{id}")
.addPathParam("id", id);

ConductorClientRequest request = requestBuilder.build();

ConductorClientResponse<String> resp = client.execute(request, new TypeReference<>() {
});

return resp.getData();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright 2020 Conductor Authors.
* <p>
* Licensed 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 com.netflix.conductor.client.http;

import java.util.List;

import org.apache.commons.lang3.Validate;

import com.netflix.conductor.client.http.ConductorClientRequest.Method;
import com.netflix.conductor.common.metadata.workflow.SharedResourceModel;

import com.fasterxml.jackson.core.type.TypeReference;

/**
* Client for resource sharing operations in Conductor
*/
public final class ResourceSharingClient {

private ConductorClient client;

/** Creates a default resource sharing client */
public ResourceSharingClient() {
}

public ResourceSharingClient(ConductorClient client) {
this.client = client;
}

/**
* Kept only for backwards compatibility
*
* @param rootUri basePath for the ApiClient
*/
@Deprecated
public void setRootURI(String rootUri) {
if (client != null) {
client.shutdown();
}
client = new ConductorClient(rootUri);
}

/**
* Share a resource with another user or group
*
* @param resourceType Type of resource to share (e.g., "WORKFLOW", "TASK")
* @param resourceName Name of the resource to share
* @param sharedWith User or group to share the resource with
*/
public void shareResource(String resourceType, String resourceName, String sharedWith) {
Validate.notBlank(resourceType, "ResourceType cannot be blank");
Validate.notBlank(resourceName, "ResourceName cannot be blank");
Validate.notBlank(sharedWith, "SharedWith cannot be blank");

ConductorClientRequest request = ConductorClientRequest.builder()
.method(Method.POST)
.path("/share/shareResource")
.addQueryParam("resourceType", resourceType)
.addQueryParam("resourceName", resourceName)
.addQueryParam("sharedWith", sharedWith)
.build();

client.execute(request);
}

/**
* Remove sharing of a resource with a user or group
*
* @param resourceType Type of resource to unshare
* @param resourceName Name of the resource to unshare
* @param sharedWith User or group to remove sharing from
*/
public void removeSharingResource(String resourceType, String resourceName, String sharedWith) {
Validate.notBlank(resourceType, "ResourceType cannot be blank");
Validate.notBlank(resourceName, "ResourceName cannot be blank");
Validate.notBlank(sharedWith, "SharedWith cannot be blank");

ConductorClientRequest request = ConductorClientRequest.builder()
.method(Method.DELETE)
.path("/share/removeSharingResource")
.addQueryParam("resourceType", resourceType)
.addQueryParam("resourceName", resourceName)
.addQueryParam("sharedWith", sharedWith)
.build();

client.execute(request);
}

/**
* Get all shared resources accessible to the current user
*
* @return List of shared resources
*/
public List<SharedResourceModel> getSharedResources() {
ConductorClientRequest request = ConductorClientRequest.builder()
.method(Method.GET)
.path("/share/getSharedResources")
.build();

ConductorClientResponse<List<SharedResourceModel>> resp = client.execute(request, new TypeReference<>() {
});

return resp.getData();
}

/**
* Get shared resources filtered by resource type
*
* @param resourceType Type of resource to filter by
* @return List of shared resources of the specified type
*/
public List<SharedResourceModel> getSharedResources(String resourceType) {
Validate.notBlank(resourceType, "ResourceType cannot be blank");

ConductorClientRequest request = ConductorClientRequest.builder()
.method(Method.GET)
.path("/share/getSharedResources")
.addQueryParam("resourceType", resourceType)
.build();

ConductorClientResponse<List<SharedResourceModel>> resp = client.execute(request, new TypeReference<>() {
});

return resp.getData();
}

/**
* Check if a specific resource is shared with a user or group
*
* @param resourceType Type of resource
* @param resourceName Name of the resource
* @param sharedWith User or group to check
* @return true if the resource is shared, false otherwise
*/
public boolean isResourceShared(String resourceType, String resourceName, String sharedWith) {
List<SharedResourceModel> sharedResources = getSharedResources(resourceType);
return sharedResources.stream()
.anyMatch(resource ->
resource.getResourceName().equals(resourceName) &&
resource.getSharedWith().equals(sharedWith));
}
}
Loading
Loading