Skip to content
Snippets Groups Projects
Commit aab0964f authored by Rodrigo Goncalves's avatar Rodrigo Goncalves
Browse files

Support for unstrutured SmartDataContext

parent 98244cd3
No related branches found
No related tags found
1 merge request!22Resolve "Unstructured SmartDataContext storage"
......@@ -44,12 +44,64 @@ function context($url, $domain, $content) {
return $response;
}
try {
function handle_unstructured_add() {
// Validate certificate usage and domain usage (certificate only)
$backend = new Backend(null);
$domain = $backend->domainInUse();
// Check if the required URL parameters are set
if (isset($_GET['smartDataContextId'])) {
// Retrieve headers from the original request
$headers = getallheaders();
if (isset($headers['Content-Type'], $headers['Filename'])) {
// Extract the smartdatacontextid from the URL parameters
$smartDataContextId = $_GET['smartDataContextId'];
$targetUrl = Config::config()::SMARTDATACONTEXT_API . "/unstructured/add/$domain/$smartDataContextId";
// Initialize cURL session
$ch = curl_init($targetUrl);
// Set cURL options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: ' . $headers['Content-Type'],
'Filename: ' . $headers['Filename'],
]);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
$inputData = file_get_contents('php://input');
curl_setopt($ch, CURLOPT_POSTFIELDS, $inputData); // Use php://input to directly stream input
curl_setopt($ch, CURLOPT_INFILESIZE, $_SERVER['CONTENT_LENGTH']); // Set the expected content length
// Execute the cURL request
$response = curl_exec($ch);
$http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_status == 0) {
# Could not connect to the smartdatacontext API
$http_status = 503; # Service Unavailable
$response = '{"errors": ["SmartDataContext API not available"]}';
}
http_response_code($http_status);
return $response;
} else {
http_response_code(400);
}
} else {
http_response_code(400);
}
}
try {
if (array_key_exists('docs', $_GET)) {
echo context("/docs", null, null);
} else if (array_key_exists('openapi', $_GET)) {
echo context("/openapi", null, null);
} else if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'add-unstructured') {
echo handle_unstructured_add();
} else {
$content = file_get_contents('php://input');
$json = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
......
<?php
namespace SmartDataContext\Controller;
use SmartDataContext\Persistence\MinIOClient;
use SmartDataContext\Persistence\SmartDataContextCrud;
use SmartDataContext\Persistence\DBManager;
use SmartDataContext\Domain\SmartDataContext;
......@@ -8,8 +9,6 @@ use SmartDataContext\Domain\SmartDataContext;
use Slim\Psr7\Request;
use Slim\Psr7\Response;
use OpenApi\Attributes as OA;
class Crud {
private function _basicValidation($params, $request, $response) {
......@@ -44,9 +43,6 @@ class Crud {
# Validate parameters
$errors = array_merge(
SmartDataContext::ValidateContent($content),
SmartDataContext::ValidateFeatures($features),
SmartDataContext::ValidateTimestamp($t0,$t1),
SmartDataContext::ValidateContent($content),
SmartDataContext::ValidateFeatures($features),
SmartDataContext::ValidateTimestamp($t0,$t1),
......@@ -328,4 +324,122 @@ class Crud {
}
}
function addUnstructuredData(Request $request, Response $response, array $params) {
$domain = $this->_get_value_or_default($params, 'domain', null);
$errors = [];
if (! $domain) {
$errors[] = "missing domain";
}
$smartdatacontextid = $this->_get_value_or_default($params, 'id', null);
if (! $smartdatacontextid) {
$errors[] = "missing SmartDataContext ID";
}
$contentype = $request->getHeader("Content-Type")[0];
if (! $contentype) {
$errors[] = "missing Header Content-Type";
}
$filename = $request->getHeader("Filename")[0];
if (! $filename) {
$errors[] = "missing Header Filename";
}
if ($errors) {
return $this->return_error($response, $errors, 400);
}
$persistence = new SmartDataContextCrud($this->_get_db());
$minio = new MinIOClient();
$objectid = $minio->storeUnstructuredData($domain, $request->getBody());
$result = $persistence->addUnstructuredData($domain, $smartdatacontextid, $objectid, $contentype, $filename);
if ($result['success']) {
return $this->return_json($response, ["objectId" => $objectid]);
} else {
$minio->deleteObject($domain, $objectid);
return $this->return_error($response, $result['errors'], 400);
}
}
function removeUnstructuredData(Request $request, Response $response, array $params) {
[$domain, $body, $errors] = $this->_basicValidation($params, $request, $response);
if ($errors) {
return $this->return_error($response, $errors, 400);
}
$errors = [];
$smartdatacontextid = $this->_get_value_or_default($body, 'smartDataContextId', null);
if (! isset($smartdatacontextid)) {
$errors[] = 'Missing smartDataContextId';
}
$objectid = $this->_get_value_or_default($body, 'objectId', null);
if (! isset($objectid)) {
$errors[] = 'Missing objectId';
}
if ($errors) {
return $this->return_error($response, $errors, 400);
}
$minio = new MinIOClient();
$persistence = new SmartDataContextCrud($this->_get_db());
$result = $persistence->removeUnstructuredData($domain, $smartdatacontextid, $objectid);
if ($result['success']) {
$minio->deleteObject($domain, $objectid);
return $this->return_json($response, $result['result']);
} else {
return $this->return_error($response, $result['errors'], 400);
}
}
function getUnstructuredData(Request $request, Response $response, array $params) {
[$domain, $body, $errors] = $this->_basicValidation($params, $request, $response);
$smartdatacontextid = $this->_get_value_or_default($body, 'smartDataContextId', null);
if (! isset($domain)) {
$errors[] = "missing smartDataContextId";
}
$objectid = $this->_get_value_or_default($body, 'objectId', null);
if (! isset($domain)) {
$errors[] = "missing objectId";
}
if ($errors) {
return $this->return_error($response, $errors, 400);
}
$persistence = new SmartDataContextCrud($this->_get_db());
$smartdatacontext = $persistence->get($domain, $smartdatacontextid);
if (!$smartdatacontext['success']) {
return $this->return_error($response, ['SmartDataContext not found!'], 500);
}
if (!$smartdatacontext['contents']['unstructuredData']) {
return $this->return_error($response, ['SmartDataContext without unstructured data!'], 500);
}
$objectMetaData = null;
foreach ($smartdatacontext['contents']['unstructuredData'] as $unstructuredData) {
if ($unstructuredData['id'] == $objectid) {
$objectMetaData = $unstructuredData;
break;
}
}
if (!$objectMetaData) {
return $this->return_error($response, ['objectId not found!'], 500);
}
$minio = new MinIOClient();
$objectStream = $minio->getObject($domain, $objectid);
if ($objectStream) {
$response = $response
->withHeader('Content-Type', $objectMetaData['mimetype'])
->withHeader('Content-Disposition', 'attachment; filename="' . $objectMetaData['filename'] . '"');
return $response->withBody($objectStream);
} else {
return $this->return_error($response, ["Failed to retrieve object from MinIO"], 500);
}
}
}
\ No newline at end of file
......@@ -12,10 +12,10 @@ class SmartDataContext {
}
static function ValidateFeatures($features) {
if ($features && $features['tags']) {
if ($features && array_key_exists("tags", $features) && is_array($features["tags"])) {
return [];
} else {
return ["features missing tags entry"];
return ["features missing tags entry or invalid (should be an array)"];
}
}
......
<?php
namespace SmartDataContext\Persistence;
use Ramsey\Uuid\Uuid;
class UniqueID
{
public static function generateID():string {
return Uuid::uuid4()->toString();
}
}
\ No newline at end of file
<?php
namespace SmartDataContext\Persistence;
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
use GuzzleHttp\Psr7\Utils;
use Psr\Http\Message\StreamInterface;
/**
* Simple MiniIO client using AWS SDK
*/
class MinIOClient
{
private S3Client $s3Client;
public function __construct(?string $endpoint = null, ?string $username = null, ?string $password = null, string $region = 'us-east-1')
{
$endpoint = !empty($endpoint) ? $endpoint : (getenv('MINIO_HOST') ?: 'minio');
$username = !empty($username) ? $username : (getenv('MINIO_USERNAME') ?: 'minio');
$password = !empty($password) ? $password : (getenv('MINIO_PASSWORD') ?: 'minio');
$this->s3Client = new S3Client([
'version' => 'latest',
'region' => $region, // Region is required by AWS SDK, use any valid value
'endpoint' => $endpoint,
'credentials' => [
'key' => $username,
'secret' => $password,
],
'use_path_style_endpoint' => true, // Required for MinIO
]);
}
/**
* Create a new bucket.
*
*/
public function createBucket(string $bucketName): bool
{
if (! $this->s3Client->doesBucketExist($bucketName)) {
$this->s3Client->createBucket(['Bucket' => $bucketName]);
}
return true;
}
/**
* Store a new object in a bucket using a stream.
*
*/
public function putObject(string $bucketName, string $objectKey, StreamInterface $stream): bool
{
$data = $stream->getContents();
try {
$this->s3Client->putObject([
'Bucket' => $bucketName,
'Key' => $objectKey,
'Body' => $data
]);
return true;
} catch (AwsException $e) {
echo "Error uploading object: " . $e->getMessage() . PHP_EOL;
return false;
}
}
/**
* Retrieve an object from a bucket as a stream.
*
*/
public function getObject(string $bucketName, string $objectKey):StreamInterface
{
try {
$result = $this->s3Client->getObject([
'Bucket' => $bucketName,
'Key' => $objectKey,
]);
$result['Body']->rewind();
return Utils::streamFor($result['Body']);
} catch (AwsException $e) {
throw $e;
}
}
/**
* Delete an object from a bucket.
*
*/
public function deleteObject(string $bucketName, string $objectKey): bool
{
try {
$this->s3Client->deleteObject([
'Bucket' => $bucketName,
'Key' => $objectKey,
]);
return true;
} catch (AwsException $e) {
echo "Error deleting object: " . $e->getMessage() . PHP_EOL;
return false;
}
}
/**
* Create a bucket and store a new object using a stream.
*
*/
public function storeUnstructuredData(string $domain, $stream): ?string
{
// Create the bucket
if (!$this->createBucket($domain)) {
return null; // Return null if bucket creation fails
}
// Generate a unique object ID
$objectId = UniqueID::generateID();
// Store the object in the bucket
if ($this->putObject($domain, $objectId, $stream)) {
return $objectId; // Return the object ID on success
}
return null; // Return null on failure
}
}
\ No newline at end of file
......@@ -5,7 +5,6 @@ namespace SmartDataContext\Persistence;
use Exception;
use MongoDB\Database;
use MongoDB\Collection;
use Ramsey\Uuid\Uuid;
use SmartDataContext\Domain\SmartDataContext;
class SmartDataContextCrud {
......@@ -13,10 +12,6 @@ class SmartDataContextCrud {
private Database $connection;
private static array $collections = [];
private function generateID():string {
return Uuid::uuid4()->toString();
}
function __construct(Database $dbconn) {
$this->connection = $dbconn;
SmartDataContextCrud::$collections = [];
......@@ -27,7 +22,7 @@ class SmartDataContextCrud {
$features['identifier'] = $this->build_identifier($content);
}
$id = $this->generateID();
$id = UniqueID::generateID();
$this->getCollection($domain)->insertOne([
"id" => $id,
......@@ -226,4 +221,45 @@ class SmartDataContextCrud {
}
}
public function addUnstructuredData(mixed $domain, mixed $smartdatacontextid, ?string $objectid, $contentype, $filename)
{
$smartdatacontext = json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $smartdatacontextid])), true);
if ($smartdatacontext) {
$updateData = [
'$push' => [
'unstructuredData' => [
"id" => $objectid,
"mimetype" => $contentype,
"filename" => $filename
]
]
];
$this->getCollection($domain)->updateOne(["id" => $smartdatacontextid], $updateData);
return ["success" => true, "result" => json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $smartdatacontextid])), true)];
} else {
return ["success" => false, "errors" => ["smartDataContext id not found"]];
}
}
public function removeUnstructuredData(mixed $domain, mixed $smartdatacontextid, string $objectid)
{
$smartdatacontext = json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $smartdatacontextid])), true);
if ($smartdatacontext) {
$updateData = [
'$pull' => [
'unstructuredData' => ['id' => $objectid]
]
];
$this->getCollection($domain)->updateOne(["id" => $smartdatacontextid], $updateData);
return ["success" => true, "result" => json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $smartdatacontextid])), true)];
} else {
return ["success" => false, "errors" => ["smartDataContext id not found"]];
}
}
}
\ No newline at end of file
......@@ -14,6 +14,12 @@ function setupRoutes(App $app) {
$app->post('/update/{domain}/{id}', '\SmartDataContext\Controller\Crud:update');
$app->post('/unstructured/add/{domain}/{id}', '\SmartDataContext\Controller\Crud:addUnstructuredData');
$app->post('/unstructured/remove/{domain}', '\SmartDataContext\Controller\Crud:removeUnstructuredData');
$app->post('/unstructured/get/{domain}', '\SmartDataContext\Controller\Crud:getUnstructuredData');
# Documentation
$app->get('/docs', function ($request, Response $response) {
$response->getBody()->write(file_get_contents(__DIR__ . '/swagger/swagger-ui.html'));
......
......@@ -4,7 +4,8 @@
"ramsey/uuid": "^4.7",
"slim/psr7": "^1.7",
"slim/slim": "4.*",
"zircote/swagger-php": "^4.10"
"zircote/swagger-php": "^4.10",
"aws/aws-sdk-php": "^3.320"
},
"autoload": {
"classmap": ["api/", "api/controller/", "api/domain/", "api/persistence/"]
......
This diff is collapsed.
<?php
use Slim\Psr7\Stream;
require_once 'api/setup.php';
require_once 'api/routes.php';
require 'BaseTest.php';
......@@ -27,7 +29,7 @@ class CrudTest extends BaseTest
$this->assertEquals(400, $response->getStatusCode());
$this->assertNotContains("content property empty", json_decode($response->getBody(), true)['errors']);
$this->assertContains("features missing tags entry", json_decode($response->getBody(), true)['errors']);
$this->assertContains("features missing tags entry or invalid (should be an array)", json_decode($response->getBody(), true)['errors']);
}
public function testCreateInvalidInvalidT0T1()
......@@ -48,21 +50,21 @@ class CrudTest extends BaseTest
public function testCreate()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
}
public function testCreateWithSmartDataUnit()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataUnits" => [10, 12]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataUnits" => [10, 12]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
}
public function testCreateWithInvalidSmartDataUnit()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataUnits" => ["aaa", "eee"]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataUnits" => ["aaa", "eee"]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(400, $response->getStatusCode());
$this->assertContains("smartDataUnits should be a array of longs", json_decode($response->getBody(), true)['errors']);
......@@ -70,14 +72,14 @@ class CrudTest extends BaseTest
public function testCreateWithSmartDataSources()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
}
public function testCreateWithSmartDataSourcesInvalidSignature()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffds-af-2342", [1,2,3,5]]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataSources" => ["ffds-af-2342", [1,2,3,5]]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(400, $response->getStatusCode());
$this->assertContains("ffds-af-2342 is an invalid signature", json_decode($response->getBody(), true)['errors']);
......@@ -85,7 +87,7 @@ class CrudTest extends BaseTest
public function testCreateWithSmartDataSourcesInvalidSphere()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdsaf2342", [1,2,3]]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataSources" => ["ffdsaf2342", [1,2,3]]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(400, $response->getStatusCode());
$this->assertContains("[1,2,3] is an invalid sphere", json_decode($response->getBody(), true)['errors']);
......@@ -94,7 +96,7 @@ class CrudTest extends BaseTest
public function testCreateGetWithSmartDataUnit()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataUnits" => [10, 12]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataUnits" => [10, 12]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
......@@ -114,7 +116,7 @@ class CrudTest extends BaseTest
public function testAssociateWithSmartDataSources()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$response->getBody()->rewind();
......@@ -135,7 +137,7 @@ class CrudTest extends BaseTest
public function testUnassociateWithSmartDataSources()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$response->getBody()->rewind();
......@@ -163,7 +165,7 @@ class CrudTest extends BaseTest
public function testQuery()
{
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$response->getBody()->rewind();
......@@ -192,7 +194,7 @@ class CrudTest extends BaseTest
{
$domain = "performance";
$body = array("content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataSources" => ["ffdaf2342", [1,2,3,5]]);
$response = $this->app->handle($this->_createRequest('POST', "/create/$domain", $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$response->getBody()->rewind();
......@@ -221,7 +223,7 @@ class CrudTest extends BaseTest
public function testUpdateWithTimestampsAndContent() {
// Step 1: Create a document
$body = ["content" => ["meta" => true], "features" => ["tags" => "sim"], "smartDataUnits" => [10, 12]];
$body = ["content" => ["meta" => true], "features" => ["tags" => ["sim"]], "smartDataUnits" => [10, 12]];
$response = $this->app->handle($this->_createRequest('POST', '/create/test', $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
......@@ -264,4 +266,147 @@ class CrudTest extends BaseTest
$this->assertEquals($finalBody['result']['content']['meta'], "updated", 'content meta mismatch');
}
private $testFilePath = '/tmp/testFile.bin';
private $testFileSize = 1024 * 1014 * 100; // 100MB
private function createTestFile()
{
$file = fopen($this->testFilePath, 'wb');
$data = random_bytes($this->testFileSize);
fwrite($file, $data);
fclose($file);
return $data; // return the file data to compare later
}
private function removeTestFile()
{
if (file_exists($this->testFilePath)) {
unlink($this->testFilePath);
}
}
public function testAddUnstructuredData()
{
$originalData = $this->createTestFile();
$domain = 'test';
// Create a SmartDataContext first
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]]);
$response = $this->app->handle($this->_createRequest('POST', "/create/$domain", $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$response->getBody()->rewind();
$responseBody = json_decode($response->getBody()->getContents(), true);
$this->assertArrayHasKey('result', $responseBody);
$this->assertArrayHasKey('smartDataContextId', $responseBody['result']);
$smartDataContextId = $responseBody['result']['smartDataContextId'];
// Add unstructured data
$request = $this->_createRequest('POST', "/unstructured/add/$domain/$smartDataContextId");
$request = $request->withHeader('Content-Type', 'application/octet-stream');
$request = $request->withHeader('Filename', basename($this->testFilePath));
$stream = fopen($this->testFilePath, 'rb');
$stream = new Stream($stream);
$request = $request->withBody($stream);
$response = $this->app->handle($request);
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
// Ensure the object was stored correctly
$response->getBody()->rewind();
$body = json_decode($response->getBody()->getContents(), true);
$this->assertArrayHasKey('result', $body);
$this->assertArrayHasKey('objectId', $body['result']);
$objectId = $body['result']['objectId'];
// Retrieve the stored object to confirm it matches the original data
$response = $this->app->handle($this->_createRequest('POST', "/unstructured/get/$domain", ["smartDataContextId" => $smartDataContextId, "objectId" => $objectId]));
$this->assertEquals(200, $response->getStatusCode());
$retrievedData = $response->getBody()->getContents();
$this->assertEquals($originalData, $retrievedData, "The stored data does not match the original file content");
$this->removeTestFile();
}
public function testRemoveUnstructuredData()
{
$this->createTestFile();
$domain = 'test';
// Create a SmartDataContext first and add unstructured data
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]]);
$response = $this->app->handle($this->_createRequest('POST', "/create/$domain", $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$response->getBody()->rewind();
$responseBody = json_decode($response->getBody()->getContents(), true);
$this->assertArrayHasKey('result', $responseBody);
$this->assertArrayHasKey('smartDataContextId', $responseBody['result']);
$smartDataContextId = $responseBody['result']['smartDataContextId'];
// Add unstructured data
$request = $this->_createRequest('POST', "/unstructured/add/$domain/$smartDataContextId");
$request = $request->withHeader('Content-Type', 'application/octet-stream');
$request = $request->withHeader('Filename', basename($this->testFilePath));
$request = $request->withBody(new Stream(fopen($this->testFilePath, 'rb')));
$response = $this->app->handle($request);
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$response->getBody()->rewind();
$responseBody = json_decode($response->getBody()->getContents(), true);
$this->assertArrayHasKey('result', $responseBody);
$this->assertArrayHasKey('objectId', $responseBody['result']);
$objectId = $responseBody['result']['objectId'];
// Remove the unstructured data
$body = ["smartDataContextId" => $smartDataContextId, "objectId" => $objectId];
$response = $this->app->handle($this->_createRequest('POST', "/unstructured/remove/$domain", $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$this->removeTestFile();
}
public function testGetUnstructuredData()
{
$originalData = $this->createTestFile();
$domain = 'test';
// Create a SmartDataContext first and add unstructured data
$body = array("content" => ["meta" => true], "features" => ["tags" => ["sim"]]);
$response = $this->app->handle($this->_createRequest('POST', "/create/$domain", $body));
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$response->getBody()->rewind();
$responseBody = json_decode($response->getBody()->getContents(), true);
$this->assertArrayHasKey('result', $responseBody);
$this->assertArrayHasKey('smartDataContextId', $responseBody['result']);
$smartDataContextId = $responseBody['result']['smartDataContextId'];
// Add unstructured data
$request = $this->_createRequest('POST', "/unstructured/add/$domain/$smartDataContextId");
$request = $request->withHeader('Content-Type', 'application/octet-stream');
$request = $request->withHeader('Filename', basename($this->testFilePath));
$request = $request->withBody(new Stream(fopen($this->testFilePath, 'rb')));
$response = $this->app->handle($request);
$this->assertEquals(200, $response->getStatusCode(), json_encode($response->getBody()));
$response->getBody()->rewind();
$responseBody = json_decode($response->getBody()->getContents(), true);
$this->assertArrayHasKey('result', $responseBody);
$this->assertArrayHasKey('objectId', $responseBody['result']);
$objectId = $responseBody['result']['objectId'];
// Retrieve the stored object
$response = $this->app->handle($this->_createRequest('POST', "/unstructured/get/$domain", ["smartDataContextId" => $smartDataContextId, "objectId" => $objectId]));
$this->assertEquals(200, $response->getStatusCode());
$retrievedData = $response->getBody()->getContents();
$this->assertEquals($originalData, $retrievedData, "The retrieved data does not match the original file content");
$this->removeTestFile();
}
}
......@@ -75,9 +75,22 @@ services:
- docker/variables.env
volumes:
- ./docker/ingress/config:/app/config
minio:
image: minio/minio:latest
container_name: minio
env_file:
- docker/variables.env
ports:
- "9000:9000" # Port for S3 API access
- "9001:9001" # Port for MinIO console
volumes:
- minio_data:/data # Volume for persisting data
command: server /data --console-address ":9001"
volumes:
certificates:
mariadb:
cassandra:
mongo:
minio_data:
......@@ -29,4 +29,11 @@ TIKIWIKIDB_HOST=172.18.0.1
TIKIWIKIDB_PORT=3307
TIKIWIDB_DATABASE=tikiwiki
TIKIWIKDB_USERNAME=tikiwiki
TIKIWIKIDB_PASSWORD=tikiwiki
\ No newline at end of file
TIKIWIKIDB_PASSWORD=tikiwiki
# Minio
MINIO_ROOT_USER=minioroot
MINIO_ROOT_PASSWORD=minioroot
MINIO_HOST=http://minio:9000/
MINIO_USERNAME=minioroot
MINIO_PASSWORD=minioroot
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment