In moltissime applicazioni aziendali è abbastanza frequente che gli utenti debbano gestire o archiviare documenti e file di varia natura come pdf, foto o video.
I Document Management Systems (o DMS) nascono proprio per aiutare le aziende ad organizzare e facilitare la gestione documentale.
Abbiamo già visto quanto sia semplice creare un DMS in Oracle APEX (se non ci credi leggi qui).
Tuttavia, c’è da dire che usare il database per archiviare files non è certo la scelta migliore.
Prima di tutto perché si rischia di usare tanto prezioso spazio di archiviazione per salvare dati praticamente statici.
Per non parlare del fatto che si degradano le prestazioni e si aumentano i costi e tempi di manutenzione (hai idea di quanto potrebbe durare e costare un backup?).
Per questo motivo, quando si tratta di archiviare tanti files, è più opportuno utilizzare un Data Storage dedicato.
In questo modo si garantisce che il DMS si occupi “solo” di gestire i meta-dati dei documenti e regolamentarne l’accesso mentre i files veri e propri risiedono da un’altra parte.
Quale Data Storage usare?
Beh, ne esistono davvero tanti, come ad esempio Google Drive e Share Point.
Ovviamente anche Oracle ha una sua soluzione dedicata, disponibile direttamente in Oracle Cloud, che sia chiama Oracle Object Storage.
In questo articolo desidero spiegarti come puoi integrare in pochi minuti una applicazione Oracle APEX con Oracle Object Storage.
Buona lettura!
IN QUESTO ARTICOLO
Cos’è un Object Storage
Prima di tutto vale la pena spendere qualche minuto per capire di cosa stiamo parlando.
Partiamo con il dire subito che un Object Storage è un’architettura di data storage (le altre sono i Files Storage e i Blocks Storage) in cui i documenti vengono archiviati e gestiti come veri e propri Oggetti.
All’interno di uno stesso Object Storage puoi archiviare file di formato diverso (video, documenti in formato pdf, e-mail, ecc..) e ogni file, o meglio Oggetto, è identificato da una chiave univoca e da una serie di attributi e metadati.
A differenza di un File Storage, che organizza i dati in una struttura a cartelle, in un Object-Based Storage gli oggetti sono distribuiti in una struttura piatta e l’accesso avviene attraverso API REST.
Ecco alcuni scenari in cui l’utilizzo di un Object Storage trova ampio spazio:
- Big Data: gli object storage sono fondamentali nella progettazione dei Data Lake, ovvero di quei sistemi destinati a raccogliere grandi quantità di dati grezzi il cui scopo non è ancora definito ma che attraverso tecniche di Data Mining consentiranno di estrarre informazioni e correlazioni altrimenti difficile da cogliere.
- Gestione dei Dati non Strutturati: una struttura di dati semplice e senza gerarchia è l’ideale per memorizzare dati non strutturati (es. immagini, audio, video) con scalabilità potenzialmente infinita.
- Internet of Things (IoT): i metadati possono essere particolarmente utili per raccogliere le informazioni provenienti dai dispositivi IoT come file di log, alerts o altro.
Ora che hai una idea di cosa sia un Object Storage, possiamo iniziare a fare i nostri esperimenti.
Che ne dici?
Step 1: Configura Oracle Object Storage
Il servizio Oracle Object Storage è accessibile direttamente da Oracle Cloud. Puoi utilizzarlo anche nella formula Oracle Cloud Free Tier fino ad un massimo di 10 GB di spazio.
Se hai già un account Oracle Cloud possiamo configurare molto rapidamente l’ Oracle Object Storage in questo modo:
- Collegati ad Oracle Cloud e clicca sul menù principale

- Seleziona Storage > Buckets

- Dovresti atterrare nella pagina Object Storage & Archive Storage dalla quale puoi creare ed amministrare i Buckets.

Cosa sono i Buckets?
All’interno di Oracle Object Storage un Bucket è un contenitore logico, un cestino, all’interno del quale andremo a depositare i diversi files e i documenti.
Ad esempio io ho già creato un Bucket che si chiama APPin5MinutiBucket_Test.

Creiamo un nuovo Bucket.
- Clicca su Create Bucket

- Dai un nome al Bucket e seleziona l’opzione Storage Type Standard, perfetta per realizzare un Document Management System che deve garantire accesso continuo ai documenti.
- Premi Create

- Il Bucket è stato creato. Clicca sul suo Nome

- Da qui puoi vedere i dettagli del Bucket. Clicca su Edit Visibility per gestire la visibilità del Bucket che può essere Pubblico oppure Privato (in questo secondo caso l’accesso al contenuto del Bucket è consentito solo tramite autenticazione)

- Puoi caricare files all’interno dell’Object Storage direttamente dalla console OCI cliccando sul bottone Upload.

Per il momento trascuriamo gli altri aspetti che caratterizzano la gestione dei Buckets così come quella dei files che vengono caricati al suo interno.
Concentriamoci, invece, su come integrare Oracle Object Storage con una applicazione Oracle APEX.
Step 2: Configura le Credenziali Web in Oracle APEX
Per poter utilizzare le API REST di Oracle Cloud abbiamo bisogno di creare una utenza amministrativa che abbia i grants di accesso ai servizi Object Storage.
Solo dopo potremo creare le Credenziali Web da usare per configurare le Origini Dati e le varie chiamate REST.
La cosa importante da tenere a mente è che l’utente che andrai a creare dovrà avere i diritti di accesso in lettura e scrittura all’Object Storage.
Vediamo come fare.
Configura un Gruppo
- Collegati ad Oracle Cloud e vai in Identity & Security > Groups

- Clicca Create Group

- Assegna al gruppo che stai creando un Nome e una Descrizione.
- Premi Create per completare la procedura.

Configura la Policy
- Vai in Identity & Security > Policies e premi Create Policy

- Crea una nuova Policy fatta in questo modo:
- Name: ObjectStorageManagementPolicy
- Policy Use Case: Storage Management
- Policy Template: seleziona l’opzione Let Object Storage admins manage Buckets and Objects
- Group: seleziona il gruppo che hai creato prima
- Premi Create

Grazie alla Policy che abbiamo creato, tutti gli utenti che fanno parte del Gruppo APPin5MinutiObjectStorageManager possono amministrare i Buckets e gli Oggetti in essi contenuti.
Configura l’Identity Manager
L’ultima cosa da fare è quella di mappare il Gruppo appena creato con un Gruppo Federato all’interno di Oracle Identity Cloud Service, il servizio di Identity Management disponibile sempre all’interno di Oracle Cloud.
- Vai in Identity & Security > Federation e seleziona l’Identity Provider OracleIdentityCloudService

- Vai a Groups e premi Create IDCS Group

- Assegna un nome al gruppo e premi Create

- Vai a Group Mapping e premi Add Mappings

- Collega il gruppo che hai definito nell’Identity Provider (che io ho chiamato OCI_StorageManager) con quello che hai definito in Oracle Cloud

Crea l’Utente e le API Keys
Ora possiamo finalmente creare un utente. Se non sai come fare leggi questo articolo dove spiego come configurare un le credenziali OCI che devi usare in APEX.
- Vai in Identity & Security > Users e premi Create User
- Seleziona le seguenti opzioni:
- User Type: IDCS User
- Username: apex_storage_manager
- Email: inserisci la tua e-email
- First Name e Last Name
- Groups: OCI_StorageManagers

- Entra nella pagina di dettaglio dell’utente e vai alla sezione API Keys.
- Clicca Add API Key per generare le chiavi privata e pubblica.

- Scarica nel PC il file con la Chiave Privata e premi Add

Configura le Credenziali Web
Per configurare le credenziali di accesso all’Object Storage in Oracle APEX segui le istruzioni che ho riportato in questo articolo.
Step 3: Configura l’Origine Dati REST
Creiamo prima di tutto una applicazione APEX che successivamente andremo a estendere con tutte le funzionalità di cui abbiamo bisogno.
- Accedi ad Oracle APEX e clicca Create > New Application
- Dai un nome alla tua applicazione (es: Oracle Object Storage Manager APP) e premi Create Application
Per poter interagire con l’Object Storage creeremo due Origini Dati di tipo REST per recuperare rispettivamente l’elenco dei Buckets e, per ogni Bucket, l’elenco degli Oggetti che sono contenuti al suo interno.
Ovviamente questo è un esempio e nella realtà potrai decidere tu con quali e quanti buckets la tua applicazione dovrà interagire.
Prima di procedere dobbiamo capire qual è l’URL da usare per configurare correttamente l’Origine Dati.
Per far questo dovremo recuperare 3 informazioni:
- Object Storage API End-Point
- Object Storage Namespace
- Compartment OCID
Collegati a questo link per visualizzare la lista completa degli end-points esposti dalle varie Oracle Cloud Regions.
Se, ad esempio, la Cloud Region del tuo Oracle Tenancy è Switzerland North, allora l’end-point che dovrai usare è https://objectstorage.eu-zurich-1.oraclecloud.com.
Per sapere qual è la tua Region e il Namespace del tuo Tenancy segui le seguenti istruzioni:
- Collegati ad Oracle Cloud e vai in Governance and Administration > Tenancy Details
- Da questa schermata puoi recuperare:
- Cloud Region
- Object Storage Namespace

Ecco, invece, le istruzioni per recuperare OCID del Compartment:
- Vai in Identity & Security > Compartments e copia l’OCID del Compartment all’interno del quale sono presenti i Buckets che desideri gestire da APEX

Bene, è stato un po’ laborioso ma alla fine ce l’abbiamo fatta. Possiamo finalmente mettere mano ad APEX.
Se vuoi avere qualche informazioni sulle API Oracle da usare per gestire i Buckets e Oggetti guarda qui:
List Buckets Data Source
- Collegati all’APP Builder di Oracle APEX e seleziona l’applicazione Oracle Object Storage Manager APP
- Vai in Shared Components > REST Data Source e premi Create
- Seleziona l’opzione From Scratch per creare una REST Data Source nuova e premi Next
- Inserisci le informazioni richieste:
- REST Data Source Type: Simple HTTP
- Name: list_buckets
- URL Endpoint: utilizza la seguente URL, ma prima ricordati di sostituire i placeholders con i valori che abbiamo recuperato prima
https://objectstorage.<REGION>.oraclecloud.com/n/<OBJECT_STORAGE_NAMESPACE>/b/

- Premi Next e successivamente anche Next

- Seleziona l’opzione Authentication Required e scegli dal menù a tendina le OCI Web Credential che abbiamo configurato prima.
- Premi Advanced.

- Configura un nuovo parametro di tipo Query String Variable fatto in questo modo:
- Parameter Type: Query String Variable
- Parameter Name: compartmentId
- Value: inserisci l’OCID del Compartment all’interno del quale sono presenti i Buckets che desideri gestire da APEX
- Premi Discover

- Se va tutto a buon fine, dovresti vedere l’elenco dei Buckets.
- Premi Create REST Data Source per completate l’operazione.

List Files Data Source
Ora procediamo con la configurazione dell’Origine Dati che ci permetterà di vedere gli oggetti contenuti all’interno di un buckets.
L’unica cosa che devi tenere a mente è di usare un bucket che contiene almeno un file. In caso contrario Oracle APEX non riuscirà a creare correttamente la REST Data Source.
- Sempre dall’APP Builder vai in Shared Components > REST Data Source > Create
- Seleziona l’opzione From Scratch e clicca Next
- Inserisci le seguenti informazioni
- REST Data Source Type: Simple HTTP
- Name: list_objects_bucket
- URL Endpoint: utilizza la seguente URL, molto simile alla precedente. L’unica differenza è la parte finale che contiene il parametro bucket_name
https://objectstorage.<REGION>.oraclecloud.com/n/<OBJECT_STORAGE_NAMESPACE>/b/:bucket_name/o/
- Poiché stiamo usando un endpoint con un parametro, Oracle APEX ci chiederà di specificare un valore. Andremo quindi a scrivere il nome di un bucket che sappiamo contenere almeno un oggetto.
- Premi Next e nella schermata successiva ancora Next.

- Seleziona l’opzione Authentication Required e specifica la Credenziali da usare (le stesse usate prima) e premi Advanced
- Crea un nuovo parametro di tipo Query String Variabile
- Parameter Name: fields
- Value: name,size,timeCreated,md5
- Is Static: Yes
- Premi Discover

- Se va tutto come previsto, dovresti vedere l’elenco degli oggetti contenuti all’interno del Bucket.
- Premi Create REST Data Source per completare l’operazione.

Step 4: Configura l’applicazione Oracle Object Storage Manager APP
In questa sezione del tutorial andremo a configurare una applicazione APEX in grado di manipolare gli oggetti presenti nell’Oracle Object Storage.
Value Set List_Buckets_LOV
- Accedi all’APP Builder e vai in Shared Components > Other Components > List of Values

- Premi Create per creare una nuova Lista Valori
- Name: List_Buckets_LOV
- Type: Dynamic

- Collega la LOV all’Origine Dati REST list_buckets e premi Next

- Seleziona come Return Column e Display Column la colonna NAME e premi Create

Application Definition Attributes
- Sempre dall’APP Builder vai in Shared Components > Application Definition Attributes

- Vai in Substitutions ed inserisci una nuova entry fatta in questo modo:
- Substitution String: G_BASE_URL
- Substitution Value: inserisci la seguente URL, opportunamente modificata con l’end-point corrispondente alla tua Cloud Region e con l’Object Storage Namespace del tuo Compartment
https://objectstorage.<REGION>.oraclecloud.com/n/<OBJECT_STORAGE_NAMESPACE>/

- Inserisci una nuova entry
- Substitution String: G_OCI_CREDENTIALS
- Substitution Value: inserisci il nome delle Credenziali Web

- Premi Apply Changes
Step 5: Buckets List Home Page
Configuriamo l’Home Page della nostra APP.
- Accedi all’APP Builder e seleziona l’Home Page
- Crea una Static Region di nome Select Bucket
- Crea un Page Item di nome PX_BUCKET

- Seleziona il Page Item PX_BUCKET e configura le sue proprietà
- Item Type: Select List
- Label: Bucket
- Page Action on Selection: Submit Page
- List of Values > Type: Shared Component
- List of Values: LIST_BUCKETS_LOV

- Crea un Classic Report di nome Objects List

- Seleziona il report Object List e configura le sue proprietà
- Title: Objects List
- Type: Classic Report
- Location: REST Source
- REST Source: list_objects_bucket
- Page Items to Submit: PX_BUCKET

- Espandi il nodo parameters e seleziona il parametro bucket_name

- Configura il parametro bucket_name in questo modo
- Type: Item
- Item: PX_BUCKET

- Esegui la Preview per vedere il risultato

Dopo aver selezionato il bucket dal menù a tendina, dovresti vedere l’elenco degli oggetti contenuti al suo interno.
Ci sei riuscito? Bene!
Nel prossimo paragrafo vedremo come caricare dal proprio PC un file su Object Storage usando l’applicazione APEX appena creata.
Step 6: Upload File
Per implementare la funzionalità di Upload di un file costruiremo una Pagina Modale.
- Accedi all’APP Builder e premi Create Page.
- Seleziona Blank Page e premi Next
- Dai un Nome alla Pagina e seleziona l’opzione Modal Dialog. Quando hai fatto premi Next.

- Nella schermata seguente seleziona l’opzione Do not associate this page with a navigation menu entry e premi ancora Next e successivamente Finish
Configuriamo la nostra finestra di upload.
- Crea una Page Region e al suo interno un Page Item di tipo Hidden chiamato PX_BUCKET_NAME

- Crea un Page Item di tipo File Browse chiamato PX_FILE_UPLOAD

- Seleziona il Page Item e verifica che la proprietà Storage Type sia impostata a Table APEX_APPLICATION_TEMP_FILES

- Crea una nuova Region nel Dialog Footer ed aggiungi due Page Buttons
- CANCEL
- UPLOAD

- Seleziona il Page Button CANCEL e crea una nuova Dynamic Action
- Configura una Action di tipo Cancel Dialog

- Seleziona il Page Button UPLOAD e premurati che sia impostata coma Action l’opzione Submit Page.

- Vai in Page Processes e crea un nuovo Page Process di nome UploadFile

- Seleziona il Page Process e configurane le proprietà
- Type: Execute Code
- Language: PL/SQL

- Vai alla proprietà PL/SQL Code ed inserisci il seguente script PL/SQL facendo attenzione a sostituire i nomi dei Page Items PX_FILE_UPLOAD e PX_BUCKET_NAME con quelli che hai creato tu.
DECLARE
l_request_url VARCHAR2(32767);
l_content_length NUMBER;
l_response CLOB;
upload_failed_exception EXCEPTION;
BEGIN
FOR FILE IN (SELECT *
FROM apex_application_temp_files
WHERE name = :PX_FILE_UPLOAD) LOOP
l_request_url := :G_BASE_URL
|| 'b/'
|| :PX_BUCKET_NAME
|| '/o/'
|| apex_util.url_encode(FILE.filename);
apex_web_service.G_request_headers(1).name := 'Content-Type';
apex_web_service.G_request_headers(1).value := FILE.mime_type;
l_response := apex_web_service.make_rest_request(p_url => l_request_url,
p_http_method => 'PUT',
p_body_blob => FILE.blob_content,
p_credential_static_id =>
:G_OCI_CREDENTIALS)
;
IF apex_web_service.g_status_code != 200 THEN
RAISE upload_failed_exception;
END IF;
END LOOP;
END;
- Premi OK

- Aggiungi un altro Page Process di tipo Close Dialog

Completiamo la costruzione della nostra applicazione definendo il Page Button che fa apparire la finestra modale Upload File.
- Dall’APP Builder seleziona l’Home Page e crea un nuovo Page Button di nome UPLOAD_NEW_FILE

- Seleziona il Page Button ed imposta la proprietà Action con l’opzione Redirect to Page in this Application
- Clicca su Target

- Seleziona la pagina di destinazione ed imposta il parametro

- Crea una Dynamic Action che scatta all’evento Dialog Close


- Configura una Action di tipo Refresh che servirà per aggiornare l’elenco degli Oggetti visualizzati nel Report.

Esegui la Page Preview per verificare che tutto funzioni.
- Clicca su Upload New File

- Scegli un File e premi Upload

- Il file viene caricato su Object Storage e la pagina APEX viene aggiornata mostrando l’elenco dei file contenuti nel buckets.

- Ovviamente puoi collegarti all’OCI Console per verificare che i files siano stati effettivamente caricati

Step 7: Download File
Anche in questo caso avremo bisogno di una Pagina Modale.
- Accedi all’APP Builder e crea una Pagina Modale di nome Download File

- Crea due Page Items di tipo Hidden
- PX_BUCKET_NAME
- PX_OBJECT_NAME

- Clicca su Page Process e crea un Process di nome downloadFile che dovrà essere eseguito prima di visualizzare l’Header (Before Header)

- Proprietà del Processo downloadFile:
- Type: Execute Code
- Language: PL/SQL

- Inserisci nel campo PL/SQL Code lo script PL/SQL seguente, non prima di aver sostituito i campi PX_BUCKET_NAME e PX_OBJECT_NAME con quelli che hai creato nella tua pagina
DECLARE
l_request_url VARCHAR2(32767);
l_content_type VARCHAR2(32767);
l_content_length VARCHAR2(32767);
l_response BLOB;
download_failed_exception EXCEPTION;
BEGIN
l_request_url := :G_BASE_URL || 'b/' || :PX_BUCKET_NAME || '/o/' || apex_util.Url_encode(:PX_OBJECT_NAME);
l_response := apex_web_service.Make_rest_request_b(p_url => l_request_url, p_http_method => 'GET', p_credential_static_id => :G_OCI_CREDENTIALS);
IF apex_web_service.g_status_code != 200 THEN
RAISE download_failed_exception;
END IF;
FOR i IN 1..apex_web_service.g_headers.count LOOP
IF apex_web_service.g_headers(i).name = 'Content-Length' THEN
l_content_length := apex_web_service.g_headers(i).value;
END IF;
IF apex_web_service.g_headers(i).name = 'Content-Type' THEN
l_content_type := apex_web_service.g_headers(i).value;
END IF;
END LOOP;
sys.htp.init;
IF l_content_type IS NOT NULL THEN
sys.owa_util.Mime_header(Trim(l_content_type), FALSE);
END IF;
sys.htp.P('Content-length: ' || l_content_length);
sys.htp.P('Content-Disposition: attachment; filename="'|| :P4_OBJECT_NAME || '"');
sys.htp.P('Cache-Control: max-age=3600'); -- if desired
sys.owa_util.http_header_close;
sys.wpg_docload.Download_file(l_response);
apex_application.stop_apex_engine;
END;
- Aggiungi un Process di tipo Close Dialog

- Seleziona l’Home Page ed aggiungi una Virtual Column al report Object List

- Seleziona la Colonna Virtuale e configurala come di tipo Link
- Nella proprietà Link Text inserisci la stringa “Download” e clicca sulle proprietà Target

- Specifica come destinazione la pagina modal Download File che abbiamo creato pochi minuti fa.
- Configura i parametri da passare alla pagina

- Vai alla proprietà Link Attributes ed inserisci la seguente stringa: class=”t-Button t-Button–link”

- Esegui la Page Preview e clicca su Download per scaricare il file

Step 8: Delete File
Nell’ultima parte di questo tutorial vedremo come cancellare un file dall’Object Storage.
L’approccio che seguiremo sarà quello di richiamare il codice PLSQL direttamente da una Dynamic Action usando del codice JavaScript.
- Seleziona l’Home Page ed aggiungi una Virtual Column di tipo Plain Text
- Vai alla proprietà HTML Expression ed inserisci la stringa seguente:
<button type="button" class="delete-object-button t-Button t-Button--link" data-object-name="#NAME#">Delete</button>

- Clicca sulla Page Root

- Vai alla proprietà Function and Global Variable Declaration ed inserisci il seguente codice JavaScript
var oss = {
deleteObject: function(bucketName, objectName, report) {
if(confirm('Are you sure?')) {
var result = apex.server.process('DELETE_OBJECT', {
x01: bucketName,
x02: objectName
});
result.done(function(data) {
apex.message.showPageSuccess(
'Object deleted successfully.');
apex.event.trigger(report, 'apexrefresh');
}).fail(function (jqXHR, textStatus, errorThrown) {
apex.message.alert('Failed to delete object.');
});
}
}
};
- Clicca su Dynamic Actions e crea l’Azione Dinamica deletefile

- Proprietà della Dynamic Action
- Event: Click
- Selection Type: jQuerySelector
- jQuery Selector: .delete-object-button
- Event Scope: Dynamic

- Crea una Action di tipo Execute JavaScript Code con il seguente codice (rimpiazza PX_BUCKET_NAME con il nome di quello che hai creato tu)
oss.deleteObject(
apex.item('PX_BUCKET_NAME').getValue(),
$(this.triggeringElement).data('object-name'),
this.affectedElements
);

- Vai in Page Processing e crea una nuova Ajax Callback di nome DELETE_OBJECT
- Inserisci il seguente codice PL-SQL
declare
c_bucket_name apex_application.g_x01%type :=
apex_application.g_x01;
c_object_name apex_application.g_x02%type :=
apex_application.g_x02;
l_request_url varchar2(32767);
l_response clob;
begin
l_request_url := :G_BASE_URL || 'b/' || c_bucket_name
|| '/o/' || apex_util.url_encode(c_object_name);
l_response := apex_web_service.make_rest_request(
p_url => l_request_url
, p_http_method => 'DELETE'
, p_credential_static_id => :G_OCI_CREDENTIALS
);
if apex_web_service.g_status_code != 200 then
owa_util.status_line(
nstatus => apex_web_service.g_status_code
);
sys.htp.p('{ "message": "Failed" }');
else
sys.htp.p('{ "message": "Success" }');
end if;
end;
- Aggiungi una nuova Action di tipo Refresh che si occuperà di aggiornare l’elenco dei files mostrati nel report Objects List


- Esegui la Page Preview e premi Delete

- Comparirà un messaggio di conferma. Premi OK.

- Il file viene cancellato dall’Object Storage

Conclusioni
In questo articolo abbiamo unito in un’unica soluzione le potenzialità di due componenti molto potenti di Oracle Cloud: Object Storage e Oracle APEX.
Come abbiamo visto, non è nulla di complicato e anche se non sei un esperto programmatore, grazie alle istruzioni dettagliate che ti ho fornito, sono sicuro che riuscirai a farlo anche tu.
Fammi sapere nei commenti qui sotto se ci sei riuscito!
Un abbraccio
Daniele
Buon Giorno Daniele
Relativamente al Come gestire i files su Object Storage da Oracle APEX
Ho completato con successo tutto fino allo step 6 . Riesco a vedere il Bucket name nella LOV
e nel Classic Report appaiono i due file caricati a mano
Invece per lo Step 7 ho completato le istruzioni , ma quando vado a fare l upload del file mi da un errore
1 error has occurred
ORA-20987: The requested URL has been prohibited. Contact your administrator
Avete un suggerimento ?
Ciao Fortunato
sembrerebbe un errore di network, ovvero il database non riesce a collegarsi all’host remoto.
Potresti dover verificare l’ Access Control List(ACL) del database e che abbia i grants corretti.
Un saluto
Daniele
Buon Giorno Daniele , tutto risolto , non era l’access control list ( sulla quale non sarei stato capace a intervenire , come ti avevo scritto in una risposta precedente) ma era un errore che facevo quando creavo le credenziali OCI. Ora il sistema funziona
Grazie per questa tua iniziativa