blob: 711817e8a4f60100488546e4fc813fca0ef3c5a7 [file] [log] [blame]
/*
* Copyright 2019 The Apache Software Foundation.
*
* Licensed 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.
*/
/* eslint-disable no-console */
/** Proxy renderer which uses an OpenWhisk action for
* rendering, if one matches the current request's
* resource type and extension.
*/
const openwhisk = require('openwhisk');
const getAnnotation = (act, key) => {
if(act != null) {
const annotation = act.annotations.find(ann => key == ann.key);
return annotation ? annotation.value : undefined;
}
}
// If an action matches the specified resource type (*)
// and extension (*), return its info and the content-type
// that it provides (*).
// Items marked with (*) are defined by OpenWhisk annotations
// on the actions.
// A "sling:resourceType" annotation with value "*" matches all
// resource types.
const getActionInfo = async (resourceType, extension) => {
return new Promise(resolve => {
var ow = openwhisk();
ow.actions.list()
.then(actions => {
const act = actions.find(act => {
const rtAnnotation = getAnnotation(act, 'sling:resourceType');
return ('*' == rtAnnotation || resourceType == rtAnnotation)
&& extension == getAnnotation(act, 'sling:extensions');
})
let result;
if(act) {
result = {
action: act,
contentType: getAnnotation(act, 'sling:contentType'),
};
}
resolve(result);
})
.catch(e => {
throw e;
})
})
};
const renderWithAction = (resource, actionInfo) => {
if(!actionInfo.action) {
throw Error("No Action provided, cannot render");
}
const name = actionInfo.action.name;
const blocking = true, result = true
const params = {
resource: resource
}
var ow = openwhisk();
return ow.actions.invoke({name, blocking, result, params});
};
const renderer = {
getRendererInfo : async (resourceType, extension) => {
return getActionInfo(resourceType, extension);
},
render : (resource, action) => {
return renderWithAction(resource, action);
},
}
// For testing as a standalone OpenWhisk action
// (requires installing the action with -a provide-api-key true)
// or from the command line
function main () {
return new Promise(async (resolve, reject) => {
const resource = {
title: 'cmdline title test',
body: 'cmdline body test',
}
try {
const actionInfo = await getActionInfo('microsling/somedoc', 'html');
console.log(`actionInfo=${JSON.stringify(actionInfo, 2, null)}`);
const rendered = await renderWithAction(resource, actionInfo);
console.log(`rendered=${JSON.stringify(rendered, 2, null)}`);
resolve(rendered);
} catch(e) {
reject(e);
}
});
}
// From the command line, __OW_API_HOST and __OW_API_KEY environment
// variables must be set
if (require.main === module) {
main();
}
module.exports.openWhiskRenderer = renderer;
module.exports.main = main;