Skip to content

Commit

Permalink
feat(sdk): first iteration of document support
Browse files Browse the repository at this point in the history
  • Loading branch information
chillleader committed Oct 7, 2024
1 parent 97c0e45 commit c04fc4e
Show file tree
Hide file tree
Showing 7 changed files with 329 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; 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 io.camunda.connector.api.document;

import io.camunda.connector.api.document.DocumentSource.Base64Document;
import io.camunda.connector.api.document.DocumentSource.ByteArrayDocument;
import java.util.Base64;
import java.util.Objects;

public class BasicDocument implements Document {

private final Object metadata;
private final DocumentContent content;

private BasicDocument(Object metadata, DocumentContent content) {
this.metadata = metadata;
this.content = content;
}

public static Builder builder() {
return new Builder();
}

@Override
public Object getMetadata() {
return metadata;
}

@Override
public DocumentContent getContent() {
return content;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BasicDocument that = (BasicDocument) o;
return Objects.equals(metadata, that.metadata) && Objects.equals(content, that.content);
}

@Override
public int hashCode() {
return Objects.hash(metadata, content);
}

record DocumentContentImpl(byte[] bytes) implements DocumentContent {
@Override
public byte[] getBytes() {
return bytes;
}

@Override
public String getBase64() {
return Base64.getEncoder().encodeToString(bytes);
}
}

public static class Builder {
private Object metadata;
private byte[] content;

public Builder metadata(Object metadata) {
this.metadata = metadata;
return this;
}

public Builder content(byte[] content) {
this.content = content;
return this;
}

public Builder source(DocumentSource source) {
if (source instanceof ByteArrayDocument byteArrayDocument) {
return content(byteArrayDocument.content());
} else if (source instanceof Base64Document base64Document) {
return content(Base64.getDecoder().decode(base64Document.content()));
} else {
throw new IllegalArgumentException("Unsupported source type: " + source.getClass());
}
}

public BasicDocument build() {
if (content == null) {
throw new IllegalArgumentException("Content must not be null");
}
return new BasicDocument(metadata, new DocumentContentImpl(content));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; 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 io.camunda.connector.api.document;

/**
* Represents a uniform document (file) object that can be passed between connectors and used in the
* FEEL engine.
*/
public interface Document {

/**
* Domain-specific metadata that can be attached to the document. When a file is consumed by a
* connector as input, the metadata originates from the
*/
Object getMetadata();

/** Document content */
DocumentContent getContent();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; 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 io.camunda.connector.api.document;

public interface DocumentContent {

byte[] getBytes();

String getBase64();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; 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 io.camunda.connector.api.document;

public sealed interface DocumentSource {

record Base64Document(String content) implements DocumentSource {
public Base64Document {
if (content == null) {
throw new IllegalArgumentException("Content must not be null");
}
}
}

record ByteArrayDocument(byte[] content) implements DocumentSource {
public ByteArrayDocument {
if (content == null) {
throw new IllegalArgumentException("Content must not be null");
}
}
}

record ReferenceDocument(String reference) implements DocumentSource {
public ReferenceDocument {
if (reference == null) {
throw new IllegalArgumentException("Reference must not be null");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; 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 io.camunda.connector.document.jackson;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import io.camunda.connector.api.document.BasicDocument;
import io.camunda.connector.api.document.Document;
import java.io.IOException;
import java.util.Base64;

/** A Jackson deserializer to handle {@link Document} objects. */
public class DocumentDeserializer extends JsonDeserializer<Document> {

@Override
public Document deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException {

// TODO: support other types of file source, such as reference (invoke a connector)

String base64Content = jsonParser.getText();
byte[] decodedBytes;
try {
decodedBytes = Base64.getDecoder().decode(base64Content);
return BasicDocument.builder().content(decodedBytes).build();
} catch (IllegalArgumentException e) {
throw new IOException("File content is not a valid base64 encoded string", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; 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 io.camunda.connector.document.jackson;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import io.camunda.connector.api.document.Document;
import java.io.IOException;

public class DocumentSerializer extends JsonSerializer<Document> {

@Override
public void serialize(
Document document, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeString(document.getContent().getBase64());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; 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 io.camunda.connector.document.jackson;

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.module.SimpleModule;
import io.camunda.connector.api.document.Document;

public class JacksonModuleDocument extends SimpleModule {

@Override
public String getModuleName() {
return "JacksonModuleDocument";
}

@Override
public Version version() {
// TODO: get version from pom.xml
return new Version(0, 1, 0, null, "io.camunda", "jackson-datatype-document");
}

@Override
public void setupModule(SetupContext context) {
addDeserializer(Document.class, new DocumentDeserializer());
addSerializer(Document.class, new DocumentSerializer());
super.setupModule(context);
}
}

0 comments on commit c04fc4e

Please sign in to comment.