В этой статье я продолжу рассказ о реализации диалогового пользовательского интерфейса для FlexDeploy поверх Oracle Digital Assistant и
Проект Fn . Сегодня я собираюсь перенести серверный API, работающий вокруг моего чат-бота, в облако, поэтому все решение работает в облаке:

API реализован в виде набора функций Fn, собранных в приложении Fn. Прелесть Fn в том, что это просто набор контейнеров Docker, которые могут одинаково работать на вашем ноутбуке на вашем локальном движке Docker и где-то в облаке. Сказав, что я могу запустить свое приложение Fn в кластере K8s от любого облачного провайдера, как описано здесь . Но сегодня не тот день. Сегодня я собираюсь запустить свой серверный API на новом облачном сервисе Oracle Functions, который построен на основе Fn. Услуга еще не является общедоступной, но я участвую в программе ограниченной доступности, поэтому у меня есть пробный доступ к ней, я могу поиграть с ней и написать об этом в блоге. В этом решении мне пришлось избавиться от реализованного здесь Fn Flow и вернуться к моей первоначальной реализации, поскольку Fn Flow еще не поддерживается функциями Oracle. Я надеюсь, что это будет скоро, поскольку это — действительно лучшая часть.
Итак, настроив нашу среду OCI и запустив службу Oracle Functions (я здесь не репостирую руководство по Oracle), нам нужно настроить CLI Fn для связи с сервисом:
|
1
2
3
4
5
6
|
fn create context oracle_fn --provider oracle fn use context oracle_fnfn update context oracle.compartment-id MY_COMPARTMENT_IDfn update context api-url https://functions.us-phoenix-1.oraclecloud.comfn update context registry phx.ocir.io/flexagonoraclecloud/flexagon-repofn update context oracle.profile oracle_fn |
Итак, теперь наш интерфейс командной строки Fn общается с функциями Oracle . Следующим шагом является создание приложения в консоли Oracle Functions :

Теперь мы можем развернуть приложение Fn для функций Oracle :
|
1
2
3
4
5
6
7
8
9
|
Eugenes-MacBook-Pro-3:fn fedor$ ls -ltotal 8-rw-r--r--@ 1 fedor staff 12 Dec 4 15:41 app.yamldrwxr-xr-x 5 fedor staff 160 Feb 9 15:24 createsnapshotfndrwxr-xr-x 6 fedor staff 192 Feb 9 15:25 receiveFromBotFndrwxr-xr-x 6 fedor staff 192 Feb 9 15:25 sendToBotFnEugenes-MacBook-Pro-3:fn fedor$ Eugenes-MacBook-Pro-3:fn fedor$ Eugenes-MacBook-Pro-3:fn fedor$ fn deploy --all |
Сделав это, мы можем наблюдать за приложением в консоли Oracle Functions :

Следующий шаг — обновить URL-адреса API в чат-боте и на моем ноутбуке, чтобы вызывать функции в облаке вместо предыдущей локальной реализации. URL-адреса могут быть получены с помощью следующей команды:
|
1
|
fn list triggers odaapp |
До сих пор переход с моего ноутбука на Oracle Functions выглядел довольно просто и легко. Но здесь немного боли. Для вызова функций, размещенных в Oracle Functions, с запросами http, запросы должны быть подписаны, чтобы они могли проходить проверку подлинности. Реализация node.js для вызова подписанного вызова функции выглядит следующим образом:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
var fs = require('fs');var https = require('https');var os = require('os');var httpSignature = require('http-signature');var jsSHA = require("jssha");var tenancyId = "ocid1.tenancy.oc1..aaaaaaaayonz5yhpr4vxqpbdof5rn7x5pfrlgjwjycwxasf4dkexiq";var authUserId = "ocid1.user.oc1..aaaaaaaava2e3wd3cu6lew2sktd6by5hnz3d7prpgjho4oambterba";var keyFingerprint = "88:3e:71:bb:a5:ea:68:b7:56:fa:3e:5d:ea:45:60:10";var privateKeyPath = "/Users/fedor/.oci/functions_open.pem";var privateKey = fs.readFileSync(privateKeyPath, 'ascii');var identityDomain = "identity.us-ashburn-1.oraclecloud.com";function sign(request, options) { var apiKeyId = options.tenancyId + "/" + options.userId + "/" + options.keyFingerprint; var headersToSign = [ "host", "date", "(request-target)" ]; var methodsThatRequireExtraHeaders = ["POST", "PUT"]; if(methodsThatRequireExtraHeaders.indexOf(request.method.toUpperCase()) !== -1) { options.body = options.body || ""; var shaObj = new jsSHA("SHA-256", "TEXT"); shaObj.update(options.body); request.setHeader("Content-Length", options.body.length); request.setHeader("x-content-sha256", shaObj.getHash('B64')); headersToSign = headersToSign.concat([ "content-type", "content-length", "x-content-sha256" ]); } httpSignature.sign(request, { key: options.privateKey, keyId: apiKeyId, headers: headersToSign }); var newAuthHeaderValue = request.getHeader("Authorization").replace("Signature ", "Signature version=\"1\","); request.setHeader("Authorization", newAuthHeaderValue);}function handleRequest(callback) { return function(response) { var responseBody = ""; response.on('data', function(chunk) { responseBody += chunk; }); response.on('end', function() { callback(JSON.parse(responseBody)); }); }}function createSnapshot(release) { var body = release; var options = { host: 'af4qyj7yhva.us-phoenix-1.functions.oci.oraclecloud.com', path: '/t/createsnapshotfn', method: 'POST', headers: { "Content-Type": "application/text", } }; var request = https.request(options, handleRequest(function(data) { console.log(data); })); sign(request, { body: body, privateKey: privateKey, keyFingerprint: keyFingerprint, tenancyId: tenancyId, userId: authUserId }); request.end(body);}; |
Этот подход должен использоваться пользовательскими компонентами Oracle Digital Assistant и компонентом слушателя на моем ноутбуке при вызове бессерверного API, размещенного в функциях Oracle .
Это оно!
|
Опубликовано на Java Code Geeks с разрешения Евгения Федоренко, партнера нашей программы JCG . См. Оригинальную статью здесь: пользовательский интерфейс разговора с Oracle Digital Assistant и Fn Project. Часть III Переезд в облако. Мнения, высказанные участниками Java Code Geeks, являются их собственными. |