Skip to content

Commit

Permalink
refactor: migrate to dynamic properties (#178)
Browse files Browse the repository at this point in the history
  • Loading branch information
mgabelle authored Dec 20, 2024
1 parent 9db0774 commit 57b58b8
Show file tree
Hide file tree
Showing 29 changed files with 258 additions and 258 deletions.
15 changes: 9 additions & 6 deletions src/main/java/io/kestra/plugin/googleworkspace/AbstractTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.ServiceAccountCredentials;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.property.Property;
import io.kestra.core.models.tasks.Task;
import io.kestra.core.runners.RunContext;
import io.kestra.core.serializers.JacksonMapper;
Expand All @@ -30,17 +31,17 @@
public abstract class AbstractTask extends Task implements GcpInterface {
protected static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();

protected String serviceAccount;
protected Property<String> serviceAccount;

@Builder.Default
protected Integer readTimeout = 120;
protected Property<Integer> readTimeout = Property.of(120);


protected HttpCredentialsAdapter credentials(RunContext runContext) throws IllegalVariableEvaluationException, IOException {
GoogleCredentials credentials;

if (serviceAccount != null) {
String serviceAccount = runContext.render(this.serviceAccount);
String serviceAccount = runContext.render(this.serviceAccount).as(String.class).orElseThrow();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(serviceAccount.getBytes());
credentials = ServiceAccountCredentials.fromStream(byteArrayInputStream);
Logger logger = runContext.logger();
Expand All @@ -56,16 +57,18 @@ protected HttpCredentialsAdapter credentials(RunContext runContext) throws Illeg
credentials = GoogleCredentials.getApplicationDefault();
}

if (this.getScopes() != null) {
credentials = credentials.createScoped(runContext.render(this.getScopes()));
var renderedScopes = runContext.render(this.getScopes()).asList(String.class);
if (!renderedScopes.isEmpty()) {
credentials = credentials.createScoped(renderedScopes);
}

var renderedTiemout = runContext.render(this.readTimeout).as(Integer.class).orElseThrow();
return new HttpCredentialsAdapter(credentials) {
@Override
public void initialize(HttpRequest request) throws IOException {
super.initialize(request);

request.setReadTimeout(readTimeout * 1000);
request.setReadTimeout(renderedTiemout * 1000);
}
};
}
Expand Down
11 changes: 4 additions & 7 deletions src/main/java/io/kestra/plugin/googleworkspace/GcpInterface.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.kestra.plugin.googleworkspace;

import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.property.Property;
import io.swagger.v3.oas.annotations.media.Schema;

import java.util.List;
Expand All @@ -9,18 +9,15 @@ public interface GcpInterface {
@Schema(
title = "The GCP service account key"
)
@PluginProperty(dynamic = true)
String getServiceAccount();
Property<String> getServiceAccount();

@Schema(
title = "The GCP scopes to used"
)
@PluginProperty(dynamic = true)
List<String> getScopes();
Property<List<String>> getScopes();

@Schema(
title = "The read timeout for the request (in seconds)"
)
@PluginProperty(dynamic = true)
Integer getReadTimeout();
Property<Integer> getReadTimeout();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.google.auth.http.HttpCredentialsAdapter;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.property.Property;
import io.kestra.core.runners.RunContext;
import io.kestra.plugin.googleworkspace.AbstractTask;
import lombok.*;
Expand All @@ -21,8 +22,7 @@
@NoArgsConstructor
public abstract class AbstractCalendar extends AbstractTask {
@Builder.Default
@PluginProperty(dynamic = true)
protected List<String> scopes = List.of(CalendarScopes.CALENDAR);
protected Property<List<String>> scopes = Property.of(List.of(CalendarScopes.CALENDAR));

protected Calendar connection(RunContext runContext) throws IllegalVariableEvaluationException, IOException, GeneralSecurityException {
HttpCredentialsAdapter credentials = this.credentials(runContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.property.Property;
import io.kestra.core.runners.RunContext;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
Expand All @@ -28,15 +29,13 @@ public abstract class AbstractInsertEvent extends AbstractCalendar {
title = "Calendar ID."
)
@NotNull
@PluginProperty(dynamic = true)
protected String calendarId;
protected Property<String> calendarId;

@Schema(
title = "Title of the event."
)
@NotNull
@PluginProperty(dynamic = true)
protected String summary;
protected Property<String> summary;

@Schema(
title = "Description of the event."
Expand All @@ -47,8 +46,7 @@ public abstract class AbstractInsertEvent extends AbstractCalendar {
@Schema(
title = "Geographic location of the event as free-form text."
)
@PluginProperty(dynamic = true)
protected String location;
protected Property<String> location;

@Schema(
title = "Start time of the event."
Expand Down Expand Up @@ -86,14 +84,12 @@ public static class CalendarTime {
@Schema(
title = "Time of the event in the ISO 8601 Datetime format, for example, `2024-11-28T09:00:00-07:00`."
)
@PluginProperty(dynamic = true)
protected String dateTime;

protected Property<String> dateTime;

@Schema(
title = "Timezone associated with the dateTime, for example, `America/Los_Angeles`."
)
@PluginProperty(dynamic = true)
protected String timeZone;
protected Property<String> timeZone;
}

@Builder
Expand All @@ -106,45 +102,47 @@ public static class Attendee {
@Schema(
title = "Display name of the attendee."
)
@PluginProperty(dynamic = true)
protected String displayName;

protected Property<String> displayName;

@Schema(
title = "Email of the attendee."
)
@PluginProperty(dynamic = true)
protected String email;
protected Property<String> email;
}

protected Event event(RunContext runContext) throws IllegalVariableEvaluationException {
Event eventMetadata = new Event();

eventMetadata.setSummary(runContext.render(this.summary));
eventMetadata.setSummary(runContext.render(this.summary).as(String.class).orElseThrow());
if (this.description != null) {
eventMetadata.setDescription(runContext.render(this.description));
}

if (this.location != null) {
eventMetadata.setLocation(runContext.render(this.location));
eventMetadata.setLocation(runContext.render(this.location).as(String.class).orElseThrow());
}

EventDateTime eventStartTime = new EventDateTime().setDateTime(new DateTime(runContext.render(startTime.dateTime))).setTimeZone(runContext.render(startTime.timeZone));
EventDateTime eventStartTime = new EventDateTime().setDateTime(new DateTime(runContext.render(startTime.dateTime).as(String.class).orElse(null)))
.setTimeZone(runContext.render(startTime.timeZone).as(String.class).orElse(null));
eventMetadata.setStart(eventStartTime);

EventDateTime eventEndTime = new EventDateTime().setDateTime(new DateTime(runContext.render(endTime.dateTime))).setTimeZone(runContext.render(endTime.timeZone));
EventDateTime eventEndTime = new EventDateTime().setDateTime(new DateTime(runContext.render(endTime.dateTime).as(String.class).orElse(null)))
.setTimeZone(runContext.render(endTime.timeZone).as(String.class).orElse(null));
eventMetadata.setEnd(eventEndTime);

if (attendees != null && attendees.size() > 0) {
List<EventAttendee> eventAttendees = new ArrayList<>();
for (Attendee attendee: attendees){
EventAttendee eventAttendee = new EventAttendee().setDisplayName(runContext.render(attendee.displayName)).setEmail(runContext.render(attendee.email));
EventAttendee eventAttendee = new EventAttendee().setDisplayName(runContext.render(attendee.displayName).as(String.class).orElse(null))
.setEmail(runContext.render(attendee.email).as(String.class).orElse(null));
eventAttendees.add(eventAttendee);
}
eventMetadata.setAttendees(eventAttendees);
}

if (creator != null) {
Creator eventCreator = new Event.Creator().setDisplayName(runContext.render(creator.displayName)).setEmail(runContext.render(creator.email));
Creator eventCreator = new Creator().setDisplayName(runContext.render(creator.displayName).as(String.class).orElse(null))
.setEmail(runContext.render(creator.email).as(String.class).orElse(null));
eventMetadata.setCreator(eventCreator);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,14 @@ public Output run(RunContext runContext) throws Exception {

Event eventMetadata = event(runContext);

var renderedCalendarId= runContext.render(calendarId).as(String.class).orElseThrow();
Event event = service
.events()
.insert(calendarId, eventMetadata)
.insert(renderedCalendarId, eventMetadata)
.setFields("id")
.execute();

logger.debug("Inserted event '{}' in calendar '{}'", event.getId(), calendarId);
logger.debug("Inserted event '{}' in calendar '{}'", event.getId(), renderedCalendarId);

return Output
.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.api.services.drive.model.File;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.property.Property;
import io.kestra.core.runners.RunContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.EqualsAndHashCode;
Expand All @@ -22,15 +23,13 @@ public abstract class AbstractCreate extends AbstractDrive {
@Schema(
title = "The destination path"
)
@PluginProperty(dynamic = true)
protected List<String> parents;
protected Property<List<String>> parents;

@Schema(
title = "The name of the file",
description = "This is not necessarily unique within a folder"
)
@PluginProperty(dynamic = true)
protected String name;
protected Property<String> name;

@Schema(
title = "A short description of the file."
Expand All @@ -45,32 +44,31 @@ public abstract class AbstractCreate extends AbstractDrive {
"with a Google Doc MIME type, the uploaded content will be imported if possible. " +
"The supported import formats are published [here](https://developers.google.com/drive/api/v3/mime-types)."
)
@PluginProperty(dynamic = true)
protected String mimeType;
protected Property<String> mimeType;

@Schema(
title = "ID of the Team Drive the file resides in."
)
@PluginProperty(dynamic = true)
protected String teamDriveId;
protected Property<String> teamDriveId;

protected File file(RunContext runContext) throws IllegalVariableEvaluationException {
File fileMetadata = new File();

if (this.name != null) {
fileMetadata.setName(runContext.render(this.name));
fileMetadata.setName(runContext.render(this.name).as(String.class).orElseThrow());
}

if (this.parents != null) {
fileMetadata.setParents(runContext.render(this.parents));
var renderedParents = runContext.render(this.parents).asList(String.class);
if (!renderedParents.isEmpty()) {
fileMetadata.setParents(renderedParents);
}

if (mimeType != null) {
fileMetadata.setMimeType(runContext.render(mimeType));
fileMetadata.setMimeType(runContext.render(mimeType).as(String.class).orElseThrow());
}

if (teamDriveId != null) {
fileMetadata.setTeamDriveId(runContext.render(teamDriveId));
fileMetadata.setTeamDriveId(runContext.render(teamDriveId).as(String.class).orElseThrow());
}

if (description != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.google.auth.http.HttpCredentialsAdapter;
import io.kestra.core.exceptions.IllegalVariableEvaluationException;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.property.Property;
import io.kestra.core.runners.RunContext;
import io.kestra.plugin.googleworkspace.AbstractTask;
import lombok.*;
Expand All @@ -21,8 +22,7 @@
@NoArgsConstructor
public abstract class AbstractDrive extends AbstractTask {
@Builder.Default
@PluginProperty(dynamic = true)
protected List<String> scopes = List.of(DriveScopes.DRIVE);
protected Property<List<String>> scopes = Property.of(List.of(DriveScopes.DRIVE));

Drive connection(RunContext runContext) throws IllegalVariableEvaluationException, IOException, GeneralSecurityException {
HttpCredentialsAdapter credentials = this.credentials(runContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.kestra.core.models.annotations.Example;
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.property.Property;
import io.kestra.core.models.tasks.RunnableTask;
import io.kestra.core.runners.RunContext;
import io.swagger.v3.oas.annotations.media.Schema;
Expand Down Expand Up @@ -41,14 +42,13 @@ public class Delete extends AbstractDrive implements RunnableTask<Delete.Output>
@Schema(
title = "The file id to delete"
)
@PluginProperty(dynamic = true)
private String fileId;
private Property<String> fileId;

@Override
public Output run(RunContext runContext) throws Exception {
Drive service = this.connection(runContext);
Logger logger = runContext.logger();
String id = runContext.render(this.fileId);
String id = runContext.render(this.fileId).as(String.class).orElse(null);

Void execute = service
.files()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.kestra.core.models.annotations.Plugin;
import io.kestra.core.models.annotations.PluginProperty;
import io.kestra.core.models.executions.metrics.Counter;
import io.kestra.core.models.property.Property;
import io.kestra.core.models.tasks.RunnableTask;
import io.kestra.core.runners.RunContext;
import io.swagger.v3.oas.annotations.media.Schema;
Expand Down Expand Up @@ -44,15 +45,14 @@ public class Download extends AbstractDrive implements RunnableTask<Download.Out
@Schema(
title = "The file id to copy"
)
@PluginProperty(dynamic = true)
@NotNull
private String fileId;
private Property<String> fileId;

@Override
public Output run(RunContext runContext) throws Exception {
Drive service = this.connection(runContext);
Logger logger = runContext.logger();
String fileId = runContext.render(this.fileId);
String fileId = runContext.render(this.fileId).as(String.class).orElseThrow();

File tempFile = runContext.workingDir().createTempFile().toFile();
try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(tempFile))) {
Expand Down
Loading

0 comments on commit 57b58b8

Please sign in to comment.