This is an automated email from the ASF dual-hosted git repository.
pabloem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push:
new 858258c Support SCIO SDK via sbt projects
new 510417a Merge pull request #16563 from [BEAM-13701][Playground]
Support SCIO SDK via sbt projects
858258c is described below
commit 858258cafe0c900f0dd472b1aaa6afb0fd0446d0
Author: daria-malkova <[email protected]>
AuthorDate: Fri Jan 14 18:06:08 2022 +0300
Support SCIO SDK via sbt projects
---
playground/backend/cmd/server/controller.go | 2 +-
playground/backend/configs/SDK_SCIO.json | 10 +++
playground/backend/containers/scio/Dockerfile | 69 ++++++++++++++++++++
playground/backend/containers/scio/app.yaml | 22 +++++++
playground/backend/containers/scio/build.gradle | 74 ++++++++++++++++++++++
playground/backend/containers/scio/entrypoint.sh | 25 ++++++++
playground/backend/containers/scio/settings.gradle | 19 ++++++
.../cloud_bucket/precompiled_objects_test.go | 22 ++++---
.../internal/code_processing/code_processing.go | 2 +-
.../internal/environment/environment_service.go | 2 +-
playground/backend/internal/executors/executor.go | 2 +-
playground/backend/internal/fs_tool/fs.go | 3 +
playground/backend/internal/fs_tool/python_fs.go | 2 +-
.../internal/fs_tool/{python_fs.go => scio_fs.go} | 10 +--
.../backend/internal/preparers/java_preparers.go | 12 ++--
.../backend/internal/preparers/scio_preparers.go | 69 ++++++++++++++++++++
.../internal/setup_tools/builder/setup_builder.go | 17 ++++-
.../setup_tools/life_cycle/life_cycle_setuper.go | 50 +++++++++++++++
.../life_cycle/life_cycle_setuper_test.go | 1 -
.../backend/internal/utils/preparators_utils.go | 2 +
.../backend/internal/utils/validators_utils.go | 2 +
.../backend/internal/validators/scio_validators.go | 50 +++++++++++++++
.../backend/internal/validators/validator.go | 5 +-
playground/backend/new_scio_project.sh | 18 ++++++
settings.gradle.kts | 1 +
25 files changed, 461 insertions(+), 30 deletions(-)
diff --git a/playground/backend/cmd/server/controller.go
b/playground/backend/cmd/server/controller.go
index 1d9a334..d9dfac4 100644
--- a/playground/backend/cmd/server/controller.go
+++ b/playground/backend/cmd/server/controller.go
@@ -50,7 +50,7 @@ func (controller *playgroundController) RunCode(ctx
context.Context, info *pb.Ru
return nil, errors.InvalidArgumentError("Error during
preparing", "Incorrect sdk. Want to receive %s, but the request contains %s",
controller.env.BeamSdkEnvs.ApacheBeamSdk.String(), info.Sdk.String())
}
switch info.Sdk {
- case pb.Sdk_SDK_UNSPECIFIED, pb.Sdk_SDK_SCIO:
+ case pb.Sdk_SDK_UNSPECIFIED:
logger.Errorf("RunCode(): unimplemented sdk: %s\n", info.Sdk)
return nil, errors.InvalidArgumentError("Error during
preparing", "Sdk is not implemented yet: %s", info.Sdk.String())
}
diff --git a/playground/backend/configs/SDK_SCIO.json
b/playground/backend/configs/SDK_SCIO.json
new file mode 100644
index 0000000..0da4fb2
--- /dev/null
+++ b/playground/backend/configs/SDK_SCIO.json
@@ -0,0 +1,10 @@
+{
+ "compile_cmd": "",
+ "run_cmd": "sbt",
+ "test_cmd": "sbt",
+ "compile_args": [],
+ "run_args": [
+ "runMain"
+ ],
+ "test_args": []
+}
diff --git a/playground/backend/containers/scio/Dockerfile
b/playground/backend/containers/scio/Dockerfile
new file mode 100644
index 0000000..131cc3f
--- /dev/null
+++ b/playground/backend/containers/scio/Dockerfile
@@ -0,0 +1,69 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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
+#
+# 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.
+###############################################################################
+ARG BASE_IMAGE=openjdk:8
+FROM golang:1.17-bullseye AS build
+
+# Setup Go Environment
+ENV GOPATH /go
+ENV PATH $GOPATH/bin:$PATH
+RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
+RUN go install google.golang.org/protobuf/cmd/[email protected] &&\
+ go install google.golang.org/grpc/cmd/[email protected]
+
+# Prepare Application
+COPY src /go/src/playground/backend
+WORKDIR /go/src/playground/backend
+
+# Build Application
+RUN go mod download &&\
+ go mod tidy &&\
+ cd cmd/server &&\
+ go build -o /go/bin/server_scio_backend
+
+FROM $BASE_IMAGE
+ENV SERVER_IP=0.0.0.0
+ENV SERVER_PORT=8080
+ENV APP_WORK_DIR=/opt/playground/backend/
+ENV BEAM_SDK="SDK_SCIO"
+
+# Copy build result
+COPY --from=build /go/bin/server_scio_backend /opt/playground/backend/
+COPY --from=build /go/src/playground/backend/configs
/opt/playground/backend/configs/
+COPY --from=build /go/src/playground/backend/logging.properties
/opt/playground/backend/
+COPY --from=build /go/src/playground/backend/new_scio_project.sh
/opt/playground/backend/
+
+# Install sbt
+RUN echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | tee
/etc/apt/sources.list.d/sbt.list &&\
+echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | tee
/etc/apt/sources.list.d/sbt_old.list &&\
+curl -sL
"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823"
| apt-key add
+RUN apt-get update && apt-get install -y sbt
+
+
+## Install mitmpoxy
+RUN mkdir /opt/mitmproxy &&\
+ cd /opt/mitmproxy &&\
+ wget https://snapshots.mitmproxy.org/7.0.4/mitmproxy-7.0.4-linux.tar.gz &&\
+ tar -zxvf mitmproxy-7.0.4-linux.tar.gz &&\
+ mkdir /usr/local/share/ca-certificates/extra
+COPY entrypoint.sh /
+COPY allow_list_proxy.py /opt/mitmproxy/
+COPY allow_list.py /opt/mitmproxy/
+ENV HTTP_PROXY="http://127.0.0.1:8081"
+ENV HTTPS_PROXY="http://127.0.0.1:8081"
+
+ENTRYPOINT ["/opt/playground/backend/server_scio_backend"]
diff --git a/playground/backend/containers/scio/app.yaml
b/playground/backend/containers/scio/app.yaml
new file mode 100644
index 0000000..76e513c
--- /dev/null
+++ b/playground/backend/containers/scio/app.yaml
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * 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.
+*/
+service: default
+runtime: custom
+env: flex
+manual_scaling:
+ instances: 1
diff --git a/playground/backend/containers/scio/build.gradle
b/playground/backend/containers/scio/build.gradle
new file mode 100644
index 0000000..66e9f8c
--- /dev/null
+++ b/playground/backend/containers/scio/build.gradle
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * 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.
+ */
+
+
+apply plugin: 'org.apache.beam.module'
+apply plugin: 'base'
+applyDockerNature()
+
+def playgroundJobServerProject = "${project.path.replace('-container', '')}"
+
+description = project(playgroundJobServerProject).description + " :: Container"
+
+configurations {
+ dockerDependency
+}
+
+dependencies {
+ dockerDependency project(path: playgroundJobServerProject, configuration:
"shadow")
+}
+
+task copyDockerfileDependencies(type: Copy) {
+ copy {
+ from '../../../backend/'
+ into 'build/src'
+ exclude 'containers'
+ }
+ copy {
+ from 'entrypoint.sh'
+ into 'build/'
+ }
+ copy {
+ from '../../../infrastructure/proxy/allow_list.py'
+ into 'build/'
+ }
+ copy {
+ from '../../../infrastructure/proxy/allow_list_proxy.py'
+ into 'build/'
+ }
+ copy {
+ from '../../../playground'
+ into 'build/playground'
+ }
+}
+
+docker {
+ name containerImageName(
+ name: project.docker_image_default_repo_prefix +
"playground-backend",
+ root: project.rootProject.hasProperty(["docker-repository-root"]) ?
+ project.rootProject["docker-repository-root"] :
+ project.docker_image_default_repo_root)
+ files "./build/"
+ tags containerImageTags()
+ buildArgs(['BASE_IMAGE': project.rootProject.hasProperty(["base-image"]) ?
+ project.rootProject["base-image"] :
+ "openjdk:8" ])
+}
+
+// Ensure that we build the required resources and copy and file dependencies
from related projects
+dockerPrepare.dependsOn copyDockerfileDependencies
diff --git a/playground/backend/containers/scio/entrypoint.sh
b/playground/backend/containers/scio/entrypoint.sh
new file mode 100755
index 0000000..59df631
--- /dev/null
+++ b/playground/backend/containers/scio/entrypoint.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+#
+# 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.
+
+nohup /opt/mitmproxy/mitmdump -s /opt/mitmproxy/allow_list_proxy.py -p 8081 &
+while [ ! -f /root/.mitmproxy/mitmproxy-ca.pem ] ;
+do
+ sleep 2
+done
+openssl x509 -in /root/.mitmproxy/mitmproxy-ca.pem -inform PEM -out
/root/.mitmproxy/mitmproxy-ca.crt
+cp /root/.mitmproxy/mitmproxy-ca.crt /usr/local/share/ca-certificates/extra/
+update-ca-certificates
+/opt/playground/backend/server_scio_backend
diff --git a/playground/backend/containers/scio/settings.gradle
b/playground/backend/containers/scio/settings.gradle
new file mode 100644
index 0000000..1540be7
--- /dev/null
+++ b/playground/backend/containers/scio/settings.gradle
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * 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.
+ */
+
+rootProject.name = 'apache-beam-playground-backend'
diff --git
a/playground/backend/internal/cloud_bucket/precompiled_objects_test.go
b/playground/backend/internal/cloud_bucket/precompiled_objects_test.go
index a7114cd..9656bb8 100644
--- a/playground/backend/internal/cloud_bucket/precompiled_objects_test.go
+++ b/playground/backend/internal/cloud_bucket/precompiled_objects_test.go
@@ -165,22 +165,24 @@ func Test_appendPrecompiledObject(t *testing.T) {
name: "Test append new objects",
args: args{
objectInfo: ObjectInfo{
- Name: "",
- CloudPath: "",
- Description: "",
- Type: 0,
- Categories: []string{"Common"},
+ Name: "",
+ CloudPath: "",
+ Description: "",
+ Type: 0,
+ Categories: []string{"Common"},
+ PipelineOptions: "",
},
sdkToCategories: &SdkToCategories{},
pathToObject: "SDK_JAVA/HelloWorld",
categoryName: "Common",
},
want: &SdkToCategories{"SDK_JAVA":
CategoryToPrecompiledObjects{"Common": PrecompiledObjects{ObjectInfo{
- Name: "HelloWorld",
- CloudPath: "SDK_JAVA/HelloWorld",
- Description: "",
- Type: 0,
- Categories: []string{"Common"},
+ Name: "HelloWorld",
+ CloudPath: "SDK_JAVA/HelloWorld",
+ Description: "",
+ Type: 0,
+ Categories: []string{"Common"},
+ PipelineOptions: "",
}}}},
},
}
diff --git a/playground/backend/internal/code_processing/code_processing.go
b/playground/backend/internal/code_processing/code_processing.go
index f02171a..219c4ef 100644
--- a/playground/backend/internal/code_processing/code_processing.go
+++ b/playground/backend/internal/code_processing/code_processing.go
@@ -163,7 +163,7 @@ func compileStep(ctx context.Context, cacheService
cache.Cache, paths *fs_tool.L
errorChannel, successChannel := createStatusChannels()
var executor = executors.Executor{}
// This condition is used for cases when the playground doesn't compile
source files. For the Python code and the Go Unit Tests
- if sdkEnv.ApacheBeamSdk == pb.Sdk_SDK_PYTHON || (sdkEnv.ApacheBeamSdk
== pb.Sdk_SDK_GO && isUnitTest) {
+ if sdkEnv.ApacheBeamSdk == pb.Sdk_SDK_PYTHON || sdkEnv.ApacheBeamSdk ==
pb.Sdk_SDK_SCIO || (sdkEnv.ApacheBeamSdk == pb.Sdk_SDK_GO && isUnitTest) {
if err := processCompileSuccess(pipelineLifeCycleCtx,
[]byte(""), pipelineId, cacheService); err != nil {
return nil
}
diff --git a/playground/backend/internal/environment/environment_service.go
b/playground/backend/internal/environment/environment_service.go
index 81f733e..c940aef 100644
--- a/playground/backend/internal/environment/environment_service.go
+++ b/playground/backend/internal/environment/environment_service.go
@@ -212,7 +212,7 @@ func createExecutorConfig(apacheBeamSdk pb.Sdk, configPath
string) (*ExecutorCon
case pb.Sdk_SDK_PYTHON:
// Python sdk doesn't need any additional arguments from the
config file
case pb.Sdk_SDK_SCIO:
- return nil, errors.New("not yet supported")
+ // Scala sdk doesn't need any additional arguments from the
config file
}
return executorConfig, nil
}
diff --git a/playground/backend/internal/executors/executor.go
b/playground/backend/internal/executors/executor.go
index 15c9594..75e0fdc 100644
--- a/playground/backend/internal/executors/executor.go
+++ b/playground/backend/internal/executors/executor.go
@@ -107,7 +107,7 @@ func (ex *Executor) Run(ctx context.Context) *exec.Cmd {
if ex.runArgs.fileName != "" {
args = append(args, ex.runArgs.fileName)
}
- if ex.runArgs.pipelineOptions[0] != "" {
+ if ex.runArgs.pipelineOptions != nil && ex.runArgs.pipelineOptions[0]
!= "" {
args = append(args, ex.runArgs.pipelineOptions...)
}
cmd := exec.CommandContext(ctx, ex.runArgs.commandName, args...)
diff --git a/playground/backend/internal/fs_tool/fs.go
b/playground/backend/internal/fs_tool/fs.go
index 6a897cb..0cea7c5 100644
--- a/playground/backend/internal/fs_tool/fs.go
+++ b/playground/backend/internal/fs_tool/fs.go
@@ -40,6 +40,7 @@ type LifeCyclePaths struct {
AbsoluteExecutableFilePath string //
/path/to/workingDir/pipelinesFolder/{pipelineId}/bin/{pipelineId}.{executableFileExtension}
AbsoluteBaseFolderPath string //
/path/to/workingDir/pipelinesFolder/{pipelineId}
AbsoluteLogFilePath string //
/path/to/workingDir/pipelinesFolder/{pipelineId}/logs.log
+ ProjectDir string // /path/to/workingDir/
ExecutableName func(string) (string, error)
}
@@ -58,6 +59,8 @@ func NewLifeCycle(sdk pb.Sdk, pipelineId uuid.UUID,
pipelinesFolder string) (*Li
return newGoLifeCycle(pipelineId, pipelinesFolder), nil
case pb.Sdk_SDK_PYTHON:
return newPythonLifeCycle(pipelineId, pipelinesFolder), nil
+ case pb.Sdk_SDK_SCIO:
+ return newScioLifeCycle(pipelineId, pipelinesFolder), nil
default:
return nil, fmt.Errorf("%s isn't supported now", sdk)
}
diff --git a/playground/backend/internal/fs_tool/python_fs.go
b/playground/backend/internal/fs_tool/python_fs.go
index ba01acc..54c70ad 100644
--- a/playground/backend/internal/fs_tool/python_fs.go
+++ b/playground/backend/internal/fs_tool/python_fs.go
@@ -23,7 +23,7 @@ const (
pythonExecutableFileExtension = ".py"
)
-// newPythonLifeCycle creates LifeCycle with go SDK environment.
+// newPythonLifeCycle creates LifeCycle with python SDK environment.
func newPythonLifeCycle(pipelineId uuid.UUID, pipelinesFolder string)
*LifeCycle {
return newInterpretedLifeCycle(pipelineId, pipelinesFolder,
pythonExecutableFileExtension)
}
diff --git a/playground/backend/internal/fs_tool/python_fs.go
b/playground/backend/internal/fs_tool/scio_fs.go
similarity index 72%
copy from playground/backend/internal/fs_tool/python_fs.go
copy to playground/backend/internal/fs_tool/scio_fs.go
index ba01acc..ea8d834 100644
--- a/playground/backend/internal/fs_tool/python_fs.go
+++ b/playground/backend/internal/fs_tool/scio_fs.go
@@ -20,10 +20,12 @@ import (
)
const (
- pythonExecutableFileExtension = ".py"
+ scioExecutableFileExtension = ".scala"
)
-// newPythonLifeCycle creates LifeCycle with go SDK environment.
-func newPythonLifeCycle(pipelineId uuid.UUID, pipelinesFolder string)
*LifeCycle {
- return newInterpretedLifeCycle(pipelineId, pipelinesFolder,
pythonExecutableFileExtension)
+// newScioLifeCycle creates LifeCycle with scala SDK environment.
+func newScioLifeCycle(pipelineId uuid.UUID, pipelinesFolder string) *LifeCycle
{
+ lc := newInterpretedLifeCycle(pipelineId, pipelinesFolder,
scioExecutableFileExtension)
+ lc.Paths.ExecutableName = executableName
+ return lc
}
diff --git a/playground/backend/internal/preparers/java_preparers.go
b/playground/backend/internal/preparers/java_preparers.go
index bf604c2..14e5e4b 100644
--- a/playground/backend/internal/preparers/java_preparers.go
+++ b/playground/backend/internal/preparers/java_preparers.go
@@ -35,7 +35,7 @@ const (
newLinePattern = "\n"
pathSeparatorPattern = os.PathSeparator
tmpFileSuffix = "tmp"
- publicClassNamePattern = "public class (.*?)
[{|implements(.*)]"
+ javaPublicClassNamePattern = "public class (.*?)
[{|implements(.*)]"
)
//JavaPreparersBuilder facet of PreparersBuilder
@@ -204,31 +204,31 @@ func addNewLine(newLine bool, file *os.File) error {
func changeJavaTestFileName(args ...interface{}) error {
filePath := args[0].(string)
- className, err := getPublicClassName(filePath)
+ className, err := getPublicClassName(filePath,
javaPublicClassNamePattern)
if err != nil {
return err
}
- err = renameJavaFile(filePath, className)
+ err = renameSourceCodeFile(filePath, className)
if err != nil {
return err
}
return nil
}
-func renameJavaFile(filePath string, className string) error {
+func renameSourceCodeFile(filePath string, className string) error {
currentFileName := filepath.Base(filePath)
newFilePath := strings.Replace(filePath, currentFileName,
fmt.Sprintf("%s%s", className, filepath.Ext(currentFileName)), 1)
err := os.Rename(filePath, newFilePath)
return err
}
-func getPublicClassName(filePath string) (string, error) {
+func getPublicClassName(filePath, pattern string) (string, error) {
code, err := ioutil.ReadFile(filePath)
if err != nil {
logger.Errorf("Preparer: Error during open file: %s, err:
%s\n", filePath, err.Error())
return "", err
}
- re := regexp.MustCompile(publicClassNamePattern)
+ re := regexp.MustCompile(pattern)
className := re.FindStringSubmatch(string(code))[1]
return className, err
}
diff --git a/playground/backend/internal/preparers/scio_preparers.go
b/playground/backend/internal/preparers/scio_preparers.go
new file mode 100644
index 0000000..70cb0b1
--- /dev/null
+++ b/playground/backend/internal/preparers/scio_preparers.go
@@ -0,0 +1,69 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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
+//
+// 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 preparers
+
+const (
+ scioPublicClassNamePattern = "object (.*?) [{]"
+ scioPackagePattern = `^package [\w]+`
+)
+
+//ScioPreparersBuilder facet of PreparersBuilder
+type ScioPreparersBuilder struct {
+ PreparersBuilder
+}
+
+//ScioPreparers chains to type *PreparersBuilder and returns a
*ScioPreparersBuilder
+func (builder *PreparersBuilder) ScioPreparers() *ScioPreparersBuilder {
+ return &ScioPreparersBuilder{*builder}
+}
+
+//WithFileNameChanger adds preparer to change source code file name
+func (builder *ScioPreparersBuilder) WithFileNameChanger()
*ScioPreparersBuilder {
+ changeNamePreparer := Preparer{
+ Prepare: changeScioFileName,
+ Args: []interface{}{builder.filePath},
+ }
+ builder.AddPreparer(changeNamePreparer)
+ return builder
+}
+
+//WithPackageRemover adds preparer to remove package from the code
+func (builder *ScioPreparersBuilder) WithPackageRemover()
*ScioPreparersBuilder {
+ removePackagePreparer := Preparer{
+ Prepare: replace,
+ Args: []interface{}{builder.filePath, scioPackagePattern,
""},
+ }
+ builder.AddPreparer(removePackagePreparer)
+ return builder
+}
+
+// GetScioPreparers returns preparation methods that should be applied to Scio
code
+func GetScioPreparers(builder *PreparersBuilder) {
+ builder.ScioPreparers().WithPackageRemover().WithFileNameChanger()
+}
+
+func changeScioFileName(args ...interface{}) error {
+ filePath := args[0].(string)
+ className, err := getPublicClassName(filePath,
scioPublicClassNamePattern)
+ if err != nil {
+ return err
+ }
+ err = renameSourceCodeFile(filePath, className)
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/playground/backend/internal/setup_tools/builder/setup_builder.go
b/playground/backend/internal/setup_tools/builder/setup_builder.go
index 5209ff0..e439370 100644
--- a/playground/backend/internal/setup_tools/builder/setup_builder.go
+++ b/playground/backend/internal/setup_tools/builder/setup_builder.go
@@ -85,7 +85,7 @@ func Compiler(paths *fs_tool.LifeCyclePaths, sdkEnv
*environment.BeamEnvs) *exec
func Runner(paths *fs_tool.LifeCyclePaths, pipelineOptions string, sdkEnv
*environment.BeamEnvs) (*executors.ExecutorBuilder, error) {
sdk := sdkEnv.ApacheBeamSdk
- if sdk == pb.Sdk_SDK_JAVA {
+ if sdk == pb.Sdk_SDK_JAVA || sdk == pb.Sdk_SDK_SCIO {
pipelineOptions = utils.ReplaceSpacesWithEquals(pipelineOptions)
}
executorConfig := sdkEnv.ExecutorConfig
@@ -94,7 +94,6 @@ func Runner(paths *fs_tool.LifeCyclePaths, pipelineOptions
string, sdkEnv *envir
WithWorkingDir(paths.AbsoluteBaseFolderPath).
WithCommand(executorConfig.RunCmd).
WithArgs(executorConfig.RunArgs).
- WithPipelineOptions(strings.Split(pipelineOptions, " ")).
ExecutorBuilder
switch sdk {
@@ -108,17 +107,31 @@ func Runner(paths *fs_tool.LifeCyclePaths,
pipelineOptions string, sdkEnv *envir
WithRunner().
WithArgs(args).
WithExecutableFileName(className).
+ WithPipelineOptions(strings.Split(pipelineOptions, "
")).
ExecutorBuilder
case pb.Sdk_SDK_GO: //go run command is executable file itself
builder = builder.
WithRunner().
WithExecutableFileName("").
WithCommand(paths.AbsoluteExecutableFilePath).
+ WithPipelineOptions(strings.Split(pipelineOptions, "
")).
ExecutorBuilder
case pb.Sdk_SDK_PYTHON:
builder = builder.
WithRunner().
WithExecutableFileName(paths.AbsoluteExecutableFilePath).
+ WithPipelineOptions(strings.Split(pipelineOptions, "
")).
+ ExecutorBuilder
+ case pb.Sdk_SDK_SCIO:
+ className, err :=
paths.ExecutableName(paths.AbsoluteBaseFolderPath)
+ if err != nil {
+ return nil, fmt.Errorf("no executable file name found
for SCIO pipeline at %s", paths.AbsoluteBaseFolderPath)
+ }
+ stringArg := fmt.Sprintf("%s %s %s", executorConfig.RunArgs[0],
className, pipelineOptions)
+ builder = builder.
+ WithRunner().
+ WithWorkingDir(paths.ProjectDir).
+ WithArgs([]string{stringArg}).
ExecutorBuilder
}
return &builder, nil
diff --git
a/playground/backend/internal/setup_tools/life_cycle/life_cycle_setuper.go
b/playground/backend/internal/setup_tools/life_cycle/life_cycle_setuper.go
index b9fd155..cf7a0d2 100644
--- a/playground/backend/internal/setup_tools/life_cycle/life_cycle_setuper.go
+++ b/playground/backend/internal/setup_tools/life_cycle/life_cycle_setuper.go
@@ -24,6 +24,7 @@ import (
"github.com/google/uuid"
"io"
"os"
+ "os/exec"
"path/filepath"
"strings"
)
@@ -34,6 +35,12 @@ const (
javaLogFilePlaceholder = "{logFilePath}"
goModFileName = "go.mod"
goSumFileName = "go.sum"
+ scioProjectName = "scioproject"
+ projectPath = "scioproject/src/main/scala/scioproject"
+ logFileName = "logs.log"
+ defaultExampleInSbt = "WordCount.scala"
+ shCmd = "sh"
+ scioProject = "new_scio_project.sh"
)
// Setup returns fs_tool.LifeCycle.
@@ -65,6 +72,11 @@ func Setup(sdk pb.Sdk, code string, pipelineId uuid.UUID,
workingDir, pipelinesF
lc.DeleteFolders()
return nil, errors.New("error during create necessary
files for the Java sdk")
}
+ case pb.Sdk_SDK_SCIO:
+ if lc, err = prepareSbtFiles(lc,
lc.Paths.AbsoluteBaseFolderPath, workingDir); err != nil {
+ lc.DeleteFolders()
+ return nil, errors.New("error during create necessary
files for the SCIO sdk")
+ }
}
// create file with code
@@ -143,3 +155,41 @@ func updateJavaLogConfigFile(paths fs_tool.LifeCyclePaths)
error {
}
return nil
}
+
+func prepareSbtFiles(lc *fs_tool.LifeCycle, pipelineFolder string, workingDir
string) (*fs_tool.LifeCycle, error) {
+ cmd := exec.Command(shCmd, filepath.Join(workingDir, scioProject))
+ cmd.Dir = pipelineFolder
+ _, err := cmd.Output()
+ if err != nil {
+ return nil, err
+ }
+
+ sourceFileFolder := filepath.Join(pipelineFolder, projectPath)
+ fileName := lc.Paths.SourceFileName
+ absFileFolderPath, _ := filepath.Abs(sourceFileFolder)
+ absFilePath, _ := filepath.Abs(filepath.Join(absFileFolderPath,
fileName))
+ absLogFilePath, _ := filepath.Abs(filepath.Join(absFileFolderPath,
logFileName))
+ projectFolder, _ := filepath.Abs(filepath.Join(pipelineFolder,
scioProjectName))
+ executableName := lc.Paths.ExecutableName
+
+ _, err = exec.Command("rm", filepath.Join(absFileFolderPath,
defaultExampleInSbt)).Output()
+ if err != nil {
+ return nil, err
+ }
+
+ lc = &fs_tool.LifeCycle{
+ Paths: fs_tool.LifeCyclePaths{
+ SourceFileName: fileName,
+ AbsoluteSourceFileFolderPath: absFileFolderPath,
+ AbsoluteSourceFilePath: absFilePath,
+ ExecutableFileName: fileName,
+ AbsoluteExecutableFileFolderPath: absFileFolderPath,
+ AbsoluteExecutableFilePath: absFilePath,
+ AbsoluteBaseFolderPath: absFileFolderPath,
+ AbsoluteLogFilePath: absLogFilePath,
+ ProjectDir: projectFolder,
+ },
+ }
+ lc.Paths.ExecutableName = executableName
+ return lc, nil
+}
diff --git
a/playground/backend/internal/setup_tools/life_cycle/life_cycle_setuper_test.go
b/playground/backend/internal/setup_tools/life_cycle/life_cycle_setuper_test.go
index a698991..2138168 100644
---
a/playground/backend/internal/setup_tools/life_cycle/life_cycle_setuper_test.go
+++
b/playground/backend/internal/setup_tools/life_cycle/life_cycle_setuper_test.go
@@ -33,7 +33,6 @@ const (
javaSourceFileExtension = ".java"
javaCompiledFileExtension = ".class"
pipelinesFolder = "executable_files"
- logFileName = "logs.log"
)
func TestSetup(t *testing.T) {
diff --git a/playground/backend/internal/utils/preparators_utils.go
b/playground/backend/internal/utils/preparators_utils.go
index 876225e..eb2e61e 100644
--- a/playground/backend/internal/utils/preparators_utils.go
+++ b/playground/backend/internal/utils/preparators_utils.go
@@ -42,6 +42,8 @@ func GetPreparers(sdk pb.Sdk, filepath string, valResults
*sync.Map) (*[]prepare
preparers.GetGoPreparers(builder, isUnitTest.(bool))
case pb.Sdk_SDK_PYTHON:
preparers.GetPythonPreparers(builder)
+ case pb.Sdk_SDK_SCIO:
+ preparers.GetScioPreparers(builder)
default:
return nil, fmt.Errorf("incorrect sdk: %s", sdk)
}
diff --git a/playground/backend/internal/utils/validators_utils.go
b/playground/backend/internal/utils/validators_utils.go
index 05e402c..5d9406e 100644
--- a/playground/backend/internal/utils/validators_utils.go
+++ b/playground/backend/internal/utils/validators_utils.go
@@ -31,6 +31,8 @@ func GetValidators(sdk pb.Sdk, filepath string)
(*[]validators.Validator, error)
val = validators.GetGoValidators(filepath)
case pb.Sdk_SDK_PYTHON:
val = validators.GetPyValidators(filepath)
+ case pb.Sdk_SDK_SCIO:
+ val = validators.GetScioValidators(filepath)
default:
return nil, fmt.Errorf("incorrect sdk: %s", sdk)
}
diff --git a/playground/backend/internal/validators/scio_validators.go
b/playground/backend/internal/validators/scio_validators.go
new file mode 100644
index 0000000..d43dfe1
--- /dev/null
+++ b/playground/backend/internal/validators/scio_validators.go
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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
+//
+// 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 validators
+
+import (
+ "beam.apache.org/playground/backend/internal/fs_tool"
+)
+
+const (
+ scalaExtension = ".scala"
+)
+
+// GetScioValidators return validators methods that should be applied to scio
code
+// The last validator should check that the code is unit tests or not
+func GetScioValidators(filePath string) *[]Validator {
+ validatorArgs := make([]interface{}, 2)
+ validatorArgs[0] = filePath
+ validatorArgs[1] = scalaExtension
+ pathCheckerValidator := Validator{
+ Validator: fs_tool.CheckPathIsValid,
+ Args: validatorArgs,
+ Name: "Valid path",
+ }
+ unitTestValidator := Validator{
+ Validator: checkIsUnitTestScio,
+ Args: validatorArgs,
+ Name: UnitTestValidatorName,
+ }
+ validators := []Validator{pathCheckerValidator, unitTestValidator}
+ return &validators
+}
+
+//checkIsUnitTestScio checks if the pipeline is a UnitTest
+func checkIsUnitTestScio(args ...interface{}) (bool, error) {
+ return false, nil
+ //TODO BEAM-13702
+}
diff --git a/playground/backend/internal/validators/validator.go
b/playground/backend/internal/validators/validator.go
index 63c9e1c..cf504f7 100644
--- a/playground/backend/internal/validators/validator.go
+++ b/playground/backend/internal/validators/validator.go
@@ -16,8 +16,9 @@
package validators
const (
- UnitTestValidatorName = "UnitTest"
- KatasValidatorName = "Katas"
+ UnitTestValidatorName = "UnitTest"
+ KatasValidatorName = "Katas"
+ PublicClassValidatorName = "ClassName"
)
type Validator struct {
diff --git a/playground/backend/new_scio_project.sh
b/playground/backend/new_scio_project.sh
new file mode 100644
index 0000000..d274c78
--- /dev/null
+++ b/playground/backend/new_scio_project.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+#
+# 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.
+
+yes scioproject | sbt new spotify/scio-template.g8
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 50f37c2..9b71524 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -63,6 +63,7 @@ include(":playground:frontend")
include(":playground:backend:containers:java")
include(":playground:backend:containers:go")
include(":playground:backend:containers:python")
+include(":playground:backend:containers:scio")
include(":runners:core-construction-java")
include(":runners:core-java")
include(":runners:direct-java")