66import io .temporal .api .enums .v1 .EventType ;
77import java .io .UnsupportedEncodingException ;
88import java .net .URI ;
9- import java .net .URISyntaxException ;
109import java .net .URLDecoder ;
1110import java .net .URLEncoder ;
1211import java .nio .charset .StandardCharsets ;
@@ -21,8 +20,6 @@ public class LinkConverter {
2120 private static final Logger log = LoggerFactory .getLogger (LinkConverter .class );
2221
2322 private static final String linkPathFormat = "temporal:///namespaces/%s/workflows/%s/%s/history" ;
24- private static final String linkPathNexusOperationFormat =
25- "temporal:///namespaces/%s/nexus-operations/%s/%s/details" ;
2623 private static final String linkReferenceTypeKey = "referenceType" ;
2724 private static final String linkEventIDKey = "eventID" ;
2825 private static final String linkEventTypeKey = "eventType" ;
@@ -33,12 +30,6 @@ public class LinkConverter {
3330 private static final String requestIDReferenceType =
3431 Link .WorkflowEvent .RequestIdReference .getDescriptor ().getName ();
3532
36- // Fully-qualified proto descriptor names used as the `type` field on nexus.v1.Link. Match the
37- // server's Nexus link converter so links round-trip cleanly across SDKs.
38- private static final String workflowEventType = Link .WorkflowEvent .getDescriptor ().getFullName ();
39- private static final String nexusOperationType =
40- Link .NexusOperation .getDescriptor ().getFullName ();
41-
4233 public static io .temporal .api .nexus .v1 .Link workflowEventToNexusLink (Link .WorkflowEvent we ) {
4334 try {
4435
@@ -169,142 +160,6 @@ public static Link nexusLinkToWorkflowEvent(io.temporal.api.nexus.v1.Link nexusL
169160 return link .build ();
170161 }
171162
172- /**
173- * Encode a {@link Link.NexusOperation} (a link to a standalone Nexus operation) into the (url,
174- * type) form used on the Nexus wire. URL format matches the canonical server implementation:
175- * {@code temporal:///namespaces/{ns}/nexus-operations/{op_id}/{run_id}/details}.
176- */
177- public static io .temporal .api .nexus .v1 .Link nexusOperationToNexusLink (Link .NexusOperation no ) {
178- try {
179- String url =
180- String .format (
181- linkPathNexusOperationFormat ,
182- URLEncoder .encode (no .getNamespace (), StandardCharsets .UTF_8 .toString ()),
183- URLEncoder .encode (no .getOperationId (), StandardCharsets .UTF_8 .toString ())
184- .replace ("+" , "%20" ),
185- URLEncoder .encode (no .getRunId (), StandardCharsets .UTF_8 .toString ()));
186- return io .temporal .api .nexus .v1 .Link .newBuilder ()
187- .setUrl (url )
188- .setType (nexusOperationType )
189- .build ();
190- } catch (UnsupportedEncodingException e ) {
191- log .error ("Failed to encode NexusOperation Nexus link URL" , e );
192- }
193- return null ;
194- }
195-
196- /**
197- * Decode a {@code nexus.v1.Link} whose {@code type} is {@code Link.NexusOperation} into a {@code
198- * common.v1.Link} carrying a {@link Link.NexusOperation} variant. The URL must match the format
199- * produced by {@link #nexusOperationToNexusLink}.
200- */
201- public static Link nexusLinkToNexusOperation (io .temporal .api .nexus .v1 .Link nexusLink ) {
202- try {
203-
204- // Lots of if statements, but this way we double-check the validity of the link
205- // passed in.
206- URI uri = new URI (nexusLink .getUrl ());
207- if (!"temporal" .equals (uri .getScheme ())) {
208- log .error (
209- "Failed to parse NexusOperation Nexus link URL: invalid scheme: {}" , uri .getScheme ());
210- return null ;
211- }
212-
213- StringTokenizer st = new StringTokenizer (uri .getRawPath (), "/" );
214- if (!st .hasMoreTokens () || !"namespaces" .equals (st .nextToken ())) {
215- log .error (
216- "Failed to parse NexusOperation Nexus link URL: invalid path: {}" , uri .getRawPath ());
217- return null ;
218- }
219- if (!st .hasMoreTokens ()) {
220- log .error (
221- "Failed to parse NexusOperation Nexus link URL: invalid path: {}" , uri .getRawPath ());
222- return null ;
223- }
224- String namespace = URLDecoder .decode (st .nextToken (), StandardCharsets .UTF_8 .toString ());
225- if (!st .hasMoreTokens () || !"nexus-operations" .equals (st .nextToken ())) {
226- log .error (
227- "Failed to parse NexusOperation Nexus link URL: invalid path: {}" , uri .getRawPath ());
228- return null ;
229- }
230- if (!st .hasMoreTokens ()) {
231- log .error (
232- "Failed to parse NexusOperation Nexus link URL: invalid path: {}" , uri .getRawPath ());
233- return null ;
234- }
235- String operationId = URLDecoder .decode (st .nextToken (), StandardCharsets .UTF_8 .toString ());
236- if (!st .hasMoreTokens ()) {
237- log .error (
238- "Failed to parse NexusOperation Nexus link URL: invalid path: {}" , uri .getRawPath ());
239- return null ;
240- }
241- String runId = URLDecoder .decode (st .nextToken (), StandardCharsets .UTF_8 .toString ());
242- if (!st .hasMoreTokens () || !"details" .equals (st .nextToken ())) {
243- log .error (
244- "Failed to parse NexusOperation Nexus link URL: invalid path: {}" , uri .getRawPath ());
245- return null ;
246- }
247- if (st .hasMoreTokens ()) {
248- log .error (
249- "Failed to parse NexusOperation Nexus link URL: extra tokens after 'details': {}" ,
250- uri .getRawPath ());
251- return null ;
252- }
253-
254- return Link .newBuilder ()
255- .setNexusOperation (
256- Link .NexusOperation .newBuilder ()
257- .setNamespace (namespace )
258- .setOperationId (operationId )
259- .setRunId (runId ))
260- .build ();
261- } catch (URISyntaxException | UnsupportedEncodingException e ) {
262- log .error ("Failed to parse NexusOperation Nexus link URL" , e );
263- return null ;
264- }
265- }
266-
267- /**
268- * Encode a {@code common.v1.Link} into the Nexus-wire {@code nexus.v1.Link} (url, type) form,
269- * dispatching on the link's variant. Returns {@code null} (with a warn log) for variants the SDK
270- * does not yet know how to encode ({@code Activity}, {@code BatchJob}, unset) — match the
271- * server's link-converter behavior so we stay in lockstep.
272- */
273- public static io .temporal .api .nexus .v1 .Link commonLinkToNexusLink (Link commonLink ) {
274- switch (commonLink .getVariantCase ()) {
275- case WORKFLOW_EVENT :
276- return workflowEventToNexusLink (commonLink .getWorkflowEvent ());
277- case NEXUS_OPERATION :
278- return nexusOperationToNexusLink (commonLink .getNexusOperation ());
279- default :
280- log .warn (
281- "Cannot encode common.v1.Link variant {} as nexus.v1.Link: no encoder implemented" ,
282- commonLink .getVariantCase ());
283- return null ;
284- }
285- }
286-
287- /**
288- * Decode a Nexus-wire {@code nexus.v1.Link} (url, type) into a {@code common.v1.Link},
289- * dispatching on the link's {@code type} field. Returns {@code null} (with a warn log) for types
290- * the SDK does not yet know how to decode.
291- */
292- public static Link nexusLinkToCommonLink (io .temporal .api .nexus .v1 .Link nexusLink ) {
293- String type = nexusLink .getType ();
294- if (workflowEventType .equals (type )) {
295- return nexusLinkToWorkflowEvent (nexusLink );
296- }
297- if (nexusOperationType .equals (type )) {
298- return nexusLinkToNexusOperation (nexusLink );
299- }
300- log .warn (
301- "Cannot decode nexus.v1.Link of type '{}' to common.v1.Link:"
302- + " no decoder implemented (url='{}')" ,
303- type ,
304- nexusLink .getUrl ());
305- return null ;
306- }
307-
308163 private static Map <String , String > parseQueryParams (URI uri ) throws UnsupportedEncodingException {
309164 final String query = uri .getQuery ();
310165 if (query == null || query .isEmpty ()) {
0 commit comments