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
72 changes: 27 additions & 45 deletions gallery/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ if (process.env.MOUNT_LOCATION || existsSync("/mnt/bucket")) {
GALLERY_PATH = process.env.MOUNT_LOCATION || "/mnt/bucket";
}

function sendResponse(res, statusCode, responseMessage) {
res.statusCode = statusCode;
return res.end(responseMessage);
}

function getFunctionEndpoint() {
if (!process.env.COLORIZER) {
return undefined;
Expand Down Expand Up @@ -57,13 +62,9 @@ async function handleHttpReq(req, res) {
pageContent = await readFile(`${basePath}/page.html`);
} catch (err) {
console.log(`Error reading page: ${err.message}`);
res.statusCode = 503;
res.end(`Error reading page: ${err.message}`);
return;
return sendResponse(res, 503, `Error reading page: ${err.message}`);
}
res.statusCode = 200;
res.end(pageContent);
return;
return sendResponse(res, 200, pageContent);
}

// This handler exposes the set of features that are available
Expand Down Expand Up @@ -91,9 +92,7 @@ async function handleHttpReq(req, res) {
if (reqPath === "/change-colors") {
req.on("error", (err) => {
console.log(`Error reading body: ${err.message}`);
res.statusCode = 503;
res.end(`Error reading body: ${err.message}`);
return;
return sendResponse(res, 503, `Error reading body: ${err.message}`);
});
let bodyBuf = Buffer.alloc(0);
req.on("data", (chunkBuf) => {
Expand All @@ -107,14 +106,15 @@ async function handleHttpReq(req, res) {
invokeColorizeFunction(payload.imageId)
.then((response) => {
console.log(`Colorizer function has been invoked successfully: '${JSON.stringify(response)}'`);
res.statusCode = 200;
res.end();
return sendResponse(res, 200);
})
.catch((reason) => {
console.error(`Error colorizing image '${payload.imageId}'`, reason);
res.statusCode = 503;
res.end(`Error changing color of image '${payload.imageId}': ${reason}`);
return;
.catch((err) => {
console.error(`Error colorizing image '${payload.imageId}'`, err);

if (err.message.indexOf("Access is denied due to invalid credentials") > -1) {
return sendResponse(res, 403, `Failed due to access permission issues`);
}
return sendResponse(res, 503, `Error changing color of image '${payload.imageId}': ${err.message}`);
});
});
return;
Expand All @@ -125,9 +125,7 @@ async function handleHttpReq(req, res) {
console.info("Uploading to COS ...");
req.on("error", (err) => {
console.log(`Error reading body: ${err.message}`);
res.statusCode = 503;
res.end(`Error reading body: ${err.message}`);
return;
return sendResponse(res, 503, `Error reading body: ${err.message}`);
});
let bodyBuf = Buffer.alloc(0);
req.on("data", (chunkBuf) => {
Expand All @@ -138,14 +136,10 @@ async function handleHttpReq(req, res) {
try {
await writeFile(`${GALLERY_PATH}/gallery-pic-${Date.now()}.png`, bodyBuf, {});
res.setHeader("Content-Type", "application/json");
res.statusCode = 200;
res.end(`{"done": "true"}`);
return;
return sendResponse(res, 200, `{"done": "true"}`);
} catch (err) {
console.log(`Error uploading picture: ${err}`);
res.statusCode = 503;
res.end(`Error uploading picture: ${err}`);
return;
return sendResponse(res, 503, `Error uploading picture: ${err}`);
}
});
return;
Expand All @@ -165,14 +159,11 @@ async function handleHttpReq(req, res) {
});

res.setHeader("Content-Type", "application/json");
res.statusCode = 200;
res.end(JSON.stringify(galleryContents));
return sendResponse(res, 200, JSON.stringify(galleryContents));
} catch (err) {
console.log(`Error listing gallery content: ${err}`);
res.statusCode = 503;
res.end(`Error listing gallery content: ${err}`);
return sendResponse(res, 503, `Error listing gallery content: ${err}`);
}
return;
}

// Handler for deleting all items in the gallery
Expand All @@ -184,12 +175,10 @@ async function handleHttpReq(req, res) {
await unlink(`${GALLERY_PATH}/${file}`);
}
res.setHeader("Content-Type", "application/json");
res.statusCode = 200;
res.end(`{"done": "true"}`);
return sendResponse(res, 200, `{"done": "true"}`);
} catch (err) {
console.log(`Error deleting gallery content: ${err}`);
res.statusCode = 503;
res.end(`Error deleting gallery content: ${err}`);
return sendResponse(res, 503, `Error deleting gallery content: ${err}`);
}
return;
}
Expand All @@ -206,9 +195,7 @@ async function handleHttpReq(req, res) {
return fd.createReadStream().pipe(res);
} catch (err) {
console.error(`Error streaming gallery content '${pictureId}'`, err);
res.statusCode = 503;
res.end(`Error streaming gallery content: ${err}`);
return;
return sendResponse(res, 503, `Error streaming gallery content: ${err}`);
}
}

Expand All @@ -218,23 +205,18 @@ async function handleHttpReq(req, res) {
}
if (reqPath.includes("..")) {
console.log(`Bad path "${reqPath}"`);
res.statusCode = 404;
res.end("Bad path");
return;
return sendResponse(res, 404, "Bad path");
}
// serve file at basePath/reqPath
let pageContent;
try {
pageContent = await readFile(`${basePath}/${reqPath}`);
} catch (err) {
console.log(`Error reading file: ${err.message}`);
res.statusCode = 404;
res.end(`Error reading file: ${err.message}`);
return;
return sendResponse(res, 404, `Error reading file: ${err.message}`);
}
res.setHeader("Content-Type", mimetypeByExtension[(reqPath.match(/\.([^.]+)$/) || [])[1]] || "text/plain");
res.statusCode = 200;
res.end(pageContent);
return sendResponse(res, 200, pageContent);
}

const server = createServer(handleHttpReq);
Expand Down
5 changes: 4 additions & 1 deletion gallery/app/page.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ <h1 class="title">Code Engine Gallery Demo</h1>
<span id="gallery-title-text">My Gallery</span>
<div id="gallery-cta-buttons"><button data-clear class="cta-clear">Clear</button></div>
</div>
<div id="gallery-subtitle" class="hidden"><span>Click on individual images to change their colors.</span></div>
<div id="gallery-subtitle" class="hidden">
<span>Click on individual images to change their colors.</span>
<span data-colorizer class="colorizer"></span>
</div>
<div id="gallery" class="row" ></div>
</div>
</div>
Expand Down
11 changes: 9 additions & 2 deletions gallery/app/page.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const ne = ["file_input", "add", "picture_preview", "progress", "upload", "clear"].reduce((p, c) => {
const ne = ["file_input", "add", "picture_preview", "progress", "upload", "clear", "colorizer"].reduce((p, c) => {
p[c] = document.querySelector(`[data-${c.replace("_", "-")}]`);
return p;
}, Object.create(null));
Expand Down Expand Up @@ -178,22 +178,29 @@ function listGalleryContent() {
console.info(`setting onclick handler for '${id}'`);
img.onclick = async () => {
console.info(`colorizer for '${id}'`);
ne.colorizer.innerText = "Colorizing ...";

const currentImage = document.getElementById(id);

// adding the disabled classname will let the image appear as not clickable
currentImage.className = "gallery-pic colorizable disabled";
try {
// trigger the color change
await fetch("/change-colors", {
const colorizeResp = await fetch("/change-colors", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: `{"imageId": "${id}"}`,
});
if (colorizeResp.status != 200) {
ne.colorizer.innerText = await colorizeResp.text();
} else {
ne.colorizer.innerText = "";
}
} catch (err) {
console.error(`Failed to change color of image '${id}'`, err);
ne.colorizer.innerText = err.message;
} finally {
currentImage.className = "gallery-pic colorizable";
}
Expand Down
6 changes: 3 additions & 3 deletions gallery/function/function.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ async function main(args) {
console.log(`Uploaded updated '${imageId}'`);

return sendJSONResponse(200, `{"success": "true"}`);
} catch (reason) {
console.error(`Error changing colors of ${imageId}`, reason);
return sendJSONResponse(503, `{"error":"Error changing colors: ${reason}"}`);
} catch (err) {
console.error(`Error changing colors of ${imageId}`, err);
return sendJSONResponse(503, `{"error":"Error changing colors: ${err.message}"}`);
}
}

Expand Down
2 changes: 1 addition & 1 deletion private-path-to-vpc-vsi/ce-app/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/IBM/CodeEngine/ce-satellite-connector
module github.com/IBM/CodeEngine/ce-private-path

go 1.23.0

Expand Down
34 changes: 23 additions & 11 deletions private-path-to-vpc-vsi/ce-app/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"

Expand All @@ -17,7 +18,7 @@ import (

var dbClient = connectToDb()

type Friendship struct {
type GuestbookEntry struct {
Name string `json:"name"`
Created int64 `json:"created"`
Greeting string `json:"greeting"`
Expand All @@ -41,39 +42,49 @@ func connectToDb() *sql.DB {
// This func will handle all incoming HTTP requests
func HandleHTTP(w http.ResponseWriter, r *http.Request) {

friendships := []Friendship{}
guestbookEntries := []GuestbookEntry{}
var (
name string
created_at int64
greeting string
)
Debug("Fetching all friendship records ...")
rows, sqlErr := dbClient.Query("SELECT name, created_at, greeting FROM myfriendships")
Debug("Fetching all guestbook entries ...")
rows, sqlErr := dbClient.Query("SELECT name, created_at, greeting FROM guestbook")
if sqlErr != nil {
log.Printf("Retrieving friendship records failed - err: " + sqlErr.Error())
log.Printf("Retrieving guestbook entries failed - err: " + sqlErr.Error())
if strings.Contains(sqlErr.Error(), "dial tcp") {
w.WriteHeader(502)
fmt.Fprintf(w, "Can't reach '%s'", os.Getenv("PGHOST"))
return
}
w.WriteHeader(500)
fmt.Fprintf(w, "%s", sqlErr.Error())
return
}
defer rows.Close()
for rows.Next() {
err := rows.Scan(&name, &created_at, &greeting)
if err != nil {
log.Printf("Scanning friendship record failed - err: " + err.Error())
log.Printf("Scanning guestbook entries failed - err: " + err.Error())
w.WriteHeader(500)
fmt.Fprintf(w, "%s", err.Error())
return
}
log.Println("Retrieved friendship records", name, created_at, greeting)
friendships = append(friendships, Friendship{Name: name, Created: created_at, Greeting: greeting})
log.Println("Retrieved guestbook records", name, created_at, greeting)
guestbookEntries = append(guestbookEntries, GuestbookEntry{Name: name, Created: created_at, Greeting: greeting})
}

Debug("Fetched %d friendship records", len(friendships))
bytes, err := json.Marshal(&friendships)
Debug("Fetched %d guestbook entries", len(guestbookEntries))
bytes, err := json.Marshal(&guestbookEntries)
if err != nil {
log.Printf("Failed to marshal response - err: " + err.Error())
w.WriteHeader(500)
fmt.Fprintf(w, "%s", err.Error())
return
}

w.Header().Add("Content-Type", "application/json")
fmt.Fprintf(w, "%s", string(bytes))

}

func main() {
Expand All @@ -96,6 +107,7 @@ func main() {

<-signals
Debug("shutting down server")
dbClient.Close()
if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("failed to shutdown server: %v", err)
}
Expand Down
39 changes: 28 additions & 11 deletions private-path-to-vpc-vsi/ce-job/job.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,46 @@ import { LoremIpsum } from "lorem-ipsum";
const { Client } = pkg;

console.log("Connecting to PostgreSQL instance...");

const client = new Client({
user: process.env.PGUSER,
password: process.env.PGPASSWORD,
host: process.env.PGHOST,
database: process.env.PGDATABASE,
port: process.env.PGPORT,
});
try {
const client = new Client({
user: process.env.PGUSER,
password: process.env.PGPASSWORD,
host: process.env.PGHOST,
database: process.env.PGDATABASE,
port: process.env.PGPORT,
});
await client.connect();

console.log("Creating myfriendships table if it does not exist...");
await client.query("CREATE TABLE IF NOT EXISTS myfriendships (id SERIAL PRIMARY KEY, name varchar(256) NOT NULL, created_at bigint NOT NULL, greeting text);");
console.log("Creating guestbook table if it does not exist...");
await client.query(
"CREATE TABLE IF NOT EXISTS guestbook (id SERIAL PRIMARY KEY, name varchar(256) NOT NULL, created_at bigint NOT NULL, greeting text);"
);

console.log("Writing into myfriendships table...");
await client.query("INSERT INTO myfriendships (name,created_at,greeting) VALUES ($1,$2,$3);", [
console.log("Writing into guestbook table...");
await client.query("INSERT INTO guestbook (name,created_at,greeting) VALUES ($1,$2,$3);", [
process.env.HOSTNAME,
Date.now(),
new LoremIpsum().generateWords(5),
]);

if (process.env.ACTION === "cleanup") {
console.log("Cleaning up table content...");
await client.query("DELETE FROM guestbook;");
}

await client.end();
console.log("Done!");
} catch (err) {
console.error("Failed to connect to PostgreSQL instance", err);

if(client) {
try {
await client.end();
} catch(error) {
// just do it
}
}

process.exit(1);
}
Loading