Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions playground/backend/cmd/server/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// 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 main

import (
pb "beam.apache.org/playground/backend/internal/api"
"context"
"github.com/google/uuid"
)

type playgroundController struct {
pb.UnimplementedPlaygroundServiceServer
}

//RunCode is running code from requests using a particular SDK
func (controller *playgroundController) RunCode(ctx context.Context, info *pb.RunCodeRequest) (*pb.RunCodeResponse, error) {
// TODO implement this method
pipelineInfo := pb.RunCodeResponse{PipelineUuid: uuid.NewString()}

return &pipelineInfo, nil
}

//CheckStatus is checking status for the specific pipeline by PipelineUuid
func (controller *playgroundController) CheckStatus(ctx context.Context, info *pb.CheckStatusRequest) (*pb.CheckStatusResponse, error) {
// TODO implement this method
status := pb.CheckStatusResponse{Status: pb.Status_STATUS_FINISHED}
return &status, nil
}

//GetRunOutput is returning output of execution for specific pipeline by PipelineUuid
func (controller *playgroundController) GetRunOutput(ctx context.Context, info *pb.GetRunOutputRequest) (*pb.GetRunOutputResponse, error) {
// TODO implement this method
pipelineResult := pb.GetRunOutputResponse{Output: "Test Pipeline Result"}

return &pipelineResult, nil
}

//GetCompileOutput is returning output of compilation for specific pipeline by PipelineUuid
func (controller *playgroundController) GetCompileOutput(ctx context.Context, info *pb.GetCompileOutputRequest) (*pb.GetCompileOutputResponse, error) {
// TODO implement this method
compileOutput := pb.GetCompileOutputResponse{Output: "test compile output"}
return &compileOutput, nil
}
128 changes: 128 additions & 0 deletions playground/backend/cmd/server/controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// 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 main

import (
pb "beam.apache.org/playground/backend/internal/api"
"context"
"github.com/google/uuid"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
"log"
"net"
"testing"
)

const bufSize = 1024 * 1024

var lis *bufconn.Listener

func TestMain(m *testing.M) {
server := setup()
defer teardown(server)
m.Run()
}

func setup() *grpc.Server {
lis = bufconn.Listen(bufSize)
s := grpc.NewServer()
pb.RegisterPlaygroundServiceServer(s, &playgroundController{})
go func() {
if err := s.Serve(lis); err != nil {
log.Fatalf("Server exited with error: %v", err)
}
}()
return s
}

func teardown(server *grpc.Server) {
server.Stop()
}

func bufDialer(context.Context, string) (net.Conn, error) {
return lis.Dial()
}
func TestPlaygroundController_RunCode(t *testing.T) {
ctx := context.Background()
conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure())
if err != nil {
t.Fatalf("Failed to dial bufnet: %v", err)
}
defer conn.Close()
client := pb.NewPlaygroundServiceClient(conn)
code := pb.RunCodeRequest{
Code: "test",
Sdk: pb.Sdk_SDK_JAVA,
}
pipelineMeta, err := client.RunCode(ctx, &code)
if err != nil {
t.Fatalf("runCode failed: %v", err)
}
log.Printf("Response: %+v", pipelineMeta)
}

func TestPlaygroundController_CheckStatus(t *testing.T) {
ctx := context.Background()
conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure())
if err != nil {
t.Fatalf("Failed to dial bufnet: %v", err)
}
defer conn.Close()
client := pb.NewPlaygroundServiceClient(conn)
pipelineMeta := pb.CheckStatusRequest{
PipelineUuid: uuid.NewString(),
}
status, err := client.CheckStatus(ctx, &pipelineMeta)
if err != nil {
t.Fatalf("runCode failed: %v", err)
}
log.Printf("Response: %+v", status)
}

func TestPlaygroundController_GetCompileOutput(t *testing.T) {
ctx := context.Background()
conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure())
if err != nil {
t.Fatalf("Failed to dial bufnet: %v", err)
}
defer conn.Close()
client := pb.NewPlaygroundServiceClient(conn)
pipelineMeta := pb.GetCompileOutputRequest{
PipelineUuid: uuid.NewString(),
}
compileOutput, err := client.GetCompileOutput(ctx, &pipelineMeta)
if err != nil {
t.Fatalf("runCode failed: %v", err)
}
log.Printf("Response: %+v", compileOutput)
}

func TestPlaygroundController_GetRunOutput(t *testing.T) {
ctx := context.Background()
conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithContextDialer(bufDialer), grpc.WithInsecure())
if err != nil {
t.Fatalf("Failed to dial bufnet: %v", err)
}
defer conn.Close()
client := pb.NewPlaygroundServiceClient(conn)
pipelineMeta := pb.GetRunOutputRequest{
PipelineUuid: uuid.NewString(),
}
runOutput, err := client.GetRunOutput(ctx, &pipelineMeta)
if err != nil {
t.Fatalf("runCode failed: %v", err)
}
log.Printf("Response: %+v", runOutput)
}
37 changes: 37 additions & 0 deletions playground/backend/cmd/server/http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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 main

import (
"beam.apache.org/playground/backend/internal/environment"
"context"
"google.golang.org/grpc/grpclog"
"net/http"
)

// listenHttp binds the http.Handler on the TCP network address
func listenHttp(ctx context.Context, errChan chan error, envs environment.ServerEnvs, handler http.Handler) {
grpclog.Infof("listening HTTP at %s\n", envs.Address())
if err := http.ListenAndServe(envs.Address(), handler); err != nil {
errChan <- err
return
}
for {
select {
case <-ctx.Done():
return
}
}
}
52 changes: 50 additions & 2 deletions playground/backend/cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,57 @@
package main

import (
"beam.apache.org/playground/backend/internal/executors"
pb "beam.apache.org/playground/backend/internal/api"
"beam.apache.org/playground/backend/internal/environment"
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this PR serving as a placeholder or do we need to include the environment library as part of this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, I've synced all dependencies locally however include only server in this PR. That's just a placeholder

"context"
"github.com/improbable-eng/grpc-web/go/grpcweb"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
"log"
"os"
)

// runServer is starting http server wrapped on grpc
func runServer() error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

envService := environment.NewEnvironment()
grpcServer := grpc.NewServer()
pb.RegisterPlaygroundServiceServer(grpcServer, &playgroundController{})

grpclog.SetLoggerV2(grpclog.NewLoggerV2(os.Stdout, os.Stdout, os.Stderr))
handler := Wrap(grpcServer, getGrpcWebOptions())
errChan := make(chan error)

go listenHttp(ctx, errChan, envService.ServerEnvs, handler)

for {
select {
case err := <-errChan:
return err
case <-ctx.Done():
log.Println("interrupt signal received; stopping...")
return nil
}
}
}

// getGrpcWebOptions returns grpcweb options needed to configure wrapper
func getGrpcWebOptions() []grpcweb.Option {
return []grpcweb.Option{
grpcweb.WithCorsForRegisteredEndpointsOnly(false),
grpcweb.WithAllowNonRootResource(true),
grpcweb.WithOriginFunc(func(origin string) bool {
return true
}),
}

}

func main() {
_ = executors.GoExecutor{}
err := runServer()
if err != nil {
panic(err)
}
}
40 changes: 40 additions & 0 deletions playground/backend/cmd/server/wrapper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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 main

import (
"github.com/improbable-eng/grpc-web/go/grpcweb"
"github.com/rs/cors"
"google.golang.org/grpc"
"net/http"
)

// Wrap a grpc.Server as a http.Handler
func Wrap(svc *grpc.Server, options []grpcweb.Option) http.Handler {
wrappedServer := grpcweb.WrapServer(svc, options...)
// TODO address what is the minimum necessary
cors.AllowAll().Handler(&wrapper{
Copy link
Contributor

Choose a reason for hiding this comment

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

For a future PR we should address what is the minimum necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added TODO

svc: wrappedServer,
})
return wrappedServer
}

type wrapper struct {
svc *grpcweb.WrappedGrpcServer
}

func (wrap *wrapper) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
wrap.svc.ServeHTTP(resp, req)
}
2 changes: 2 additions & 0 deletions playground/backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ go 1.16

require (
github.com/google/uuid v1.3.0
github.com/improbable-eng/grpc-web v0.14.1
github.com/rs/cors v1.8.0
google.golang.org/grpc v1.41.0
google.golang.org/protobuf v1.27.1
)
Loading