Maximo オブジェクト (SR) の新しいビューを追加して、Work Execution アプリをカスタマイズしようとしています。ibm http://www-01.ibm.com/support/knowledgecenter/SSPJLC_7.5.1/com.ibm.si.mpl.doc_7.5.1/integration/t_ctr_int_mam.html?lang=で言及されている OSLC 統合手順を完了しました。その後、 app.xml を変更し、ビュー定義を次のように追加しました。
<view id="SR.SRView" label="Service Request">
<requiredResources>
<requiredResource name="serviceRequest">
<requiredAttribute name="description" />
</requiredResource>
</requiredResources>
<list resource="serviceRequest" attribute="description">
<sortOptions>
<sortOption label="Item">
<sortAttribute name="description" direction="asc" />
</sortOption>
</sortOptions>
<listItemTemplate layout="PlannedMaterialListItem">
<listtext resourceAttribute="description" layoutInsertAt="item1" />
</listItemTemplate>
</list>
</view>
およびリソースとして
<resource providedBy="/oslc/sp/ServiceRequest"
describedBy="http://jazz.net/ns/ism/sr/smarter_physical_infrastructure#ServiceRequest"
name="serviceRequest" pageSize="20">
<attributes>
<attribute name="description" describedByProperty="dcterms:description" />
</attributes>
</resource>
worklight studio でプレビューするときにアプリケーションをビルドした後、以下のエラーが発生します。
[WARNING ] Authentication error: Unable to respond to any of these challenges: {}
[ERROR ] FWLSE0099E: An error occurred while invoking procedure [project AnywhereWorkManager]OSLCGenericAdapter/HttpRequestFWLSE0100E: parameters: [project AnywhereWorkManager]
Failed to parse JSON string
<H1>SRVE0255E: A WebGroup/Virtual Host to handle /maximoundefined has not been defined.</H1><BR><H3>SRVE0255E: A WebGroup/Virtual Host to handle maxpc:9080 has not been defined.</H3><BR><I>IBM WebSphere Application Server</I>
FWLSE0101E: Caused by: [project AnywhereWorkManager]java.io.IOException: Unexpected character '<' on line 1, column 1java.lang.RuntimeException: Failed to parse JSON string
<H1>SRVE0255E: A WebGroup/Virtual Host to handle /maximoundefined has not been defined.</H1><BR><H3>SRVE0255E: A WebGroup/Virtual Host to handle maxpc:9080 has not been defined.</H3><BR><I>IBM WebSphere Application Server</I>
at com.worklight.adapters.http.HTTP.getResponseAsScriptable(HTTP.java:379)
at com.worklight.adapters.http.HTTP.parseResponseContent(HTTP.java:316)
at com.worklight.adapters.http.HTTP.execRequest(HTTP.java:173)
at com.worklight.adapters.http.HTTP.invoke(HTTP.java:133)
at com.worklight.integration.model.ProcedureInvoker.invokeProcedure(ProcedureInvoker.java:57)
at com.worklight.integration.model.Procedure.invoke(Procedure.java:166)
at com.worklight.integration.model.InvocationContext.call(InvocationContext.java:169)
at com.worklight.integration.model.InvocationContext.call(InvocationContext.java:38)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at com.worklight.integration.model.InvocationContext$DirectExecutorService.execute(InvocationContext.java:284)
at java.util.concurrent.AbstractExecutorService.submit(Unknown Source)
at com.worklight.integration.model.InvocationContext.submit(InvocationContext.java:138)
at com.worklight.integration.model.InvocationContextManager.submitInvocation(InvocationContextManager.java:58)
at com.worklight.integration.services.impl.DataAccessServiceImpl.callProcedure(DataAccessServiceImpl.java:497)
at com.worklight.integration.services.impl.DataAccessServiceImpl.access$100(DataAccessServiceImpl.java:56)
at com.worklight.integration.services.impl.DataAccessServiceImpl$4.execute(DataAccessServiceImpl.java:392)
at com.worklight.core.auth.impl.AuthenticationServiceBean.accessResource(AuthenticationServiceBean.java:76)
at com.worklight.integration.services.impl.DataAccessServiceImpl.invokeProcedureInternal(DataAccessServiceImpl.java:389)
at com.worklight.integration.services.impl.DataAccessServiceImpl.invokeDynamicProcedure(DataAccessServiceImpl.java:456)
at com.worklight.integration.services.impl.DataAccessServiceImpl.invokeDynamicProcedureWithEnclosingProcedureProperties(DataAccessServiceImpl.java:440)
at com.worklight.integration.js.JavaScriptIntegrationLibraryImplementation.invokeDynamicProcedureWithEnclosingProcedureProperties(JavaScriptIntegrationLibraryImplementation.java:136)
at sun.reflect.GeneratedMethodAccessor33.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:126)
at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:225)
at org.mozilla.javascript.optimizer.OptRuntime.callN(OptRuntime.java:52)
at org.mozilla.javascript.gen._integration_js_1._c_anonymous_10(/integration.js:95)
at org.mozilla.javascript.gen._integration_js_1.call(/integration.js)
at org.mozilla.javascript.optimizer.OptRuntime.call1(OptRuntime.java:32)
at org.mozilla.javascript.gen.C_3A_5CNewWorklight_Kep_SR_5CAnywhereWorkManager_5Cadapters_5COSLCGenericAdapter_OSLCGenericAdapter_impl_js_4._c_anonymous_2(C%3A%5CNewWorklight-Kep-SR%5CAnywhereWorkManager%5Cadapters%5COSLCGenericAdapter/OSLCGenericAdapter-impl.js:7)
at org.mozilla.javascript.gen.C_3A_5CNewWorklight_Kep_SR_5CAnywhereWorkManager_5Cadapters_5COSLCGenericAdapter_OSLCGenericAdapter_impl_js_4.call(C%3A%5CNewWorklight-Kep-SR%5CAnywhereWorkManager%5Cadapters%5COSLCGenericAdapter/OSLCGenericAdapter-impl.js)
at org.mozilla.javascript.JavaAdapter.doCall(JavaAdapter.java:603)
at org.mozilla.javascript.JavaAdapter.callMethod(JavaAdapter.java:578)
at adapter1.invokeHttp(<adapter>)
at com.ibm.tivoli.si.adapter.AdapterDependenciesImpl.invokeHttp(Unknown Source)
at com.ibm.tivoli.si.adapter.OSLCGenericAdapter.queryImpl(Unknown Source)
at com.ibm.tivoli.si.adapter.OSLCGenericAdapter.query(Unknown Source)
at sun.reflect.GeneratedMethodAccessor32.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:126)
at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:225)
at org.mozilla.javascript.gen.C_3A_5CNewWorklight_Kep_SR_5CAnywhereWorkManager_5Cadapters_5COSLCGenericAdapter_OSLCGenericAdapter_impl_js_4._c_query_10(C%3A%5CNewWorklight-Kep-SR%5CAnywhereWorkManager%5Cadapters%5COSLCGenericAdapter/OSLCGenericAdapter-impl.js:183)
at org.mozilla.javascript.gen.C_3A_5CNewWorklight_Kep_SR_5CAnywhereWorkManager_5Cadapters_5COSLCGenericAdapter_OSLCGenericAdapter_impl_js_4.call(C%3A%5CNewWorklight-Kep-SR%5CAnywhereWorkManager%5Cadapters%5COSLCGenericAdapter/OSLCGenericAdapter-impl.js)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091)
at org.mozilla.javascript.gen.C_3A_5CNewWorklight_Kep_SR_5CAnywhereWorkManager_5Cadapters_5COSLCGenericAdapter_OSLCGenericAdapter_impl_js_4.call(C%3A%5CNewWorklight-Kep-SR%5CAnywhereWorkManager%5Cadapters%5COSLCGenericAdapter/OSLCGenericAdapter-impl.js)
at com.worklight.integration.js.JavaScriptManager.callFunction(JavaScriptManager.java:240)
at com.worklight.integration.js.JavaScriptManager.invokeFunction(JavaScriptManager.java:214)
at com.worklight.integration.js.JavaScriptManager.invokeFunction(JavaScriptManager.java:194)
at com.worklight.integration.services.impl.AdapterManagerImpl.invokeFunction(AdapterManagerImpl.java:104)
at com.worklight.integration.js.JavaScriptProcedureInvoker.invoke(JavaScriptProcedureInvoker.java:42)
at com.worklight.integration.model.ProcedureInvoker.invokeProcedure(ProcedureInvoker.java:57)
at com.worklight.integration.model.Procedure.invoke(Procedure.java:166)
at com.worklight.integration.model.InvocationContext.call(InvocationContext.java:169)
at com.worklight.integration.model.InvocationContext.call(InvocationContext.java:38)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at com.worklight.server.util.ProjectLocal$1RunnableWrapper.run(ProjectLocal.java:267)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: Unexpected character '<' on line 1, column 1
at com.ibm.json.java.internal.Tokenizer.next(Tokenizer.java:129)
at com.ibm.json.java.internal.Parser.parse(Parser.java:57)
at com.ibm.json.java.internal.Parser.parse(Parser.java:47)
at com.ibm.json.java.JSONObject.parse(JSONObject.java:79)
at com.ibm.json.java.JSONObject.parse(JSONObject.java:91)
at com.worklight.adapters.http.HTTP.getResponseAsScriptable(HTTP.java:376)
... 63 more
ブラウザで以下の URL から結果を取得できることに注意してください。
[ http://maxpc:9080/maximo/oslc/os/oslcsrequest?_lid=maxadmin&_lpwd=maxadmin ]
助けていただければ幸いです。
アダプタ コード: (XML)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wl:adapter xmlns:wl="http://www.worklight.com/integration"
xmlns:http="http://www.worklight.com/integration/http"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="OSLCGenericAdapter">
<displayName>OSLCGenericAdapter</displayName>
<description>OSLCGenericAdapter</description>
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType" cookiePolicy="IGNORE_COOKIES">
<protocol>http</protocol>
<domain>maxpc</domain>
<port>9080</port>
</connectionPolicy>
<loadConstraints maxConcurrentConnectionsPerNode="120" />
</connectivity>
<procedure name="create" securityTest="CustomAdapter-securityTest" />
<procedure name="deleteResource" securityTest="CustomAdapter-securityTest"/>
<procedure name="get" securityTest="CustomAdapter-securityTest"/>
<procedure name="getResource" securityTest="CustomAdapter-securityTest"/>
<procedure name="query" securityTest="CustomAdapter-securityTest" connectAs="endUser" requestTimeoutInSeconds="360"/>
<procedure name="insertResource" securityTest="CustomAdapter-securityTest" connectAs="endUser"/>
<procedure name="update" securityTest="CustomAdapter-securityTest"/>
<procedure name="updateResource" securityTest="CustomAdapter-securityTest" connectAs="endUser"/>
<!-- getProperties is used before authentication, we need to keep it unprotected -->
<procedure name="getProperties" securityTest="wl_unprotected" connectAs="endUser"/>
<procedure name="login" securityTest="CustomAdapter-securityTest" connectAs="endUser"/>
<procedure name="logout" securityTest="CustomAdapter-securityTest" connectAs="endUser"/>
<procedure name="getActiveUserIdentity" securityTest="CustomAdapter-securityTest" connectAs="endUser"/>
<procedure name="changePassword" securityTest="CustomAdapter-securityTest" connectAs="endUser"/>
<procedure name="noSessionChangePassword" securityTest="wl_unprotected" connectAs="endUser"/>
<!-- when getSecurityData is called by the client, we initiate the security test to see if we are authenticated? -->
<procedure name="getSecretData" securityTest="CustomAdapter-securityTest"/>
<!-- query2 is a temporary procedure for testing authentication unique user data -->
<procedure name="query2" />
<!--
get server datetime and register before/after requesting server's information.
It will be used for calibrating the delta between server and device clocks
-->
<procedure name="getServerDate" securityTest="wl_unprotected" connectAs="endUser"/>
</wl:adapter>
アダプタ実装
var adapterDependenciesImpl = {
encodeURI : function(uri) {
return encodeURI(uri);
},
invokeHttp : function(input) {
WL.Logger.debug(JSON.stringify(input));
return WL.Server.invokeHttp(input);
},
debug : function(input) {
WL.Logger.debug(input);
}
};
var adapterDependencies = com.ibm.tivoli.si.adapter
.JsAdapterDependencies(adapterDependenciesImpl);
var adapterImpl = com.ibm.tivoli.si.adapter.OSLCGenericAdapter
.createOSLCGenericAdapter(adapterDependencies);
/**
* WL.Server.invokeHttp(parameters) accepts the following json object as an
* argument:
* { // Mandatory method : 'get' , 'post', 'delete' , 'put' or 'head' path:
* value,
* // Optional returnedContentType: any known mime-type or one of "json",
* "css", "csv", "javascript", "plain", "xml", "html" returnedContentEncoding :
* 'encoding', parameters: {name1: value1, ... }, headers: {name1: value1, ... },
* cookies: {name1: value1, ... }, body: { contentType: 'text/xml;
* charset=utf-8' or similar value, content: stringValue }, transformation: {
* type: 'default', or 'xslFile', xslFile: fileName } }
*/
function login(user, pwd, langcode) {
var credentials = adapterImpl.base64EncodeCredentials(user, pwd);
path = getBasePath() + 'login';
var heardervalue = null;
if(langcode == null)
{
heardervalue= {
'maxauth' : credentials,
'accept' : 'application/json'
}
}
else
{
heardervalue= {
'maxauth' : credentials,
'accept' : 'application/json',
'Accept-Language' : langcode
}
};
var input = {
method : 'get',
returnedContentType : 'application/json',
path : path,
headers : heardervalue
};
try {
var response = WL.Server.invokeHttp(input);
if (response['statusCode'] == 200) {
var cookies = response['responseHeaders']['Set-Cookie'];
if (!cookies) {
throw "No jsessionid returned";
}
var jsessionid = cookies.split(';')[0].split('=')[1];
WL.Logger.debug(jsessionid);
return {
sessionid : jsessionid
};
}
WL.Logger.debug(response);
return {
isSuccessful : false,
errors : [ response["oslc:Error"] ]
};
} catch (e) {
throw e;
}
}
function logout(jsessionid) {
path = getBasePath() + 'logout';
var input = {
method : 'get',
returnedContentType : 'application/json',
path : path,
cookies : {
'JSESSIONID' : jsessionid
},
headers : {
'accept' : 'application/json',
'Cookie' : 'JSESSIONID=' + jsessionid
}
};
try {
WL.Server.invokeHttp(input);
} catch (e) {
WL.Logger.error(e);
}
return {
isSuccessful : true
};
}
function getActiveUserIdentity() {
return WL.Server.getActiveUser();
}
function create(params) {
if (params == null) {
return {};
}
path = getBasePath();
var input = {
method : 'post',
returnedContentType : 'application/json',
path : path,
body : {
contentType : 'json; charset=utf-8',
content : params.resource
},
};
return WL.Server.invokeHttp(input);
}
function deleteResource(params) {
if (params == null) {
return '';
}
path = getBasePath();
path = path + '/' + params.id;
var input = {
method : 'delete',
returnedContentType : 'application/json',
path : path
};
return WL.Server.invokeHttp(input);
}
function get(params) {
if (params == null) {
return {};
}
path = getBasePath();
path = path + '/' + params.id;
var input = {
method : 'get',
returnedContentType : 'application/json',
path : path
};
return WL.Server.invokeHttp(input);
}
function query(params) {
var errors = [];
if (null == params) {
errors.push("No parameter present.");
} else {
if (null == params.url)
errors.push("Must have url parameter.");
}
if (errors.length > 0) {
// Required parameter not present
return resp = {
"isSuccessful" : "false",
"errors" : errors
};
}
var response = adapterImpl.query(params);
if ("oslc:Error" in response) {
return {
isSuccessful : false,
errors : [ response["oslc:Error"] ]
};
}
return response;
}
function getResource(params) {
var errors = [];
if (null == params) {
errors.push("No parameter present.");
} else {
if (null == params.url)
errors.push("Must have url parameter.");
}
if (errors.length > 0) {
// Required parameter not present
return resp = {
"isSuccessful" : "false",
"errors" : errors
};
}
var returnValue = adapterImpl.getResource(params);
return returnValue;
}
function insertResource(params) {
var errors = [];
if (null == params) {
errors.push("No parameter present.");
} else {
if (null == params.url)
errors.push("Must have url parameter.");
if (null == params.payload)
errors.push("Must have payload parameter.");
}
if (errors.length > 0) {
// Required parameter not present
return resp = {
"isSuccessful" : false,
"errors" : errors
};
}
var response = adapterImpl.insertResource(params);
if ("oslc:Error" in response) {
return {
isSuccessful : false,
responseHeaders: response.responseHeaders,
errors : [ response["oslc:Error"] ]
};
}
return response;
}
function updateResource(params) {
var errors = [];
if (null == params) {
errors.push("No parameter present.");
} else {
if (null == params.url)
errors.push("Must have url parameter.");
if (null == params.payload)
errors.push("Must have payload parameter.");
}
if (errors.length > 0) {
// Required parameter not present
return {
"isSuccessful" : "false",
"errors" : errors
};
}
var response = adapterImpl.updateResource(params);
if ("oslc:Error" in response) {
return {
isSuccessful : false,
responseHeaders: response.responseHeaders,
errors : [ response["oslc:Error"] ]
};
}
return response;
}
function noSessionChangePassword(params){
return changePassword(params);
}
function changePassword(params) {
var errors = [];
if (null == params) {
errors.push("No parameter . ");
}
if (errors.length > 0) {
// Required parameter not present
return resp = {
"isSuccessful" : "false",
"errors" : errors
};
}
var returnValue = adapterImpl.changePassword(params);
return returnValue;
}
function update(params) {
if (params == null) {
return {};
}
path = getBasePath();
path = path + '/' + params.id;
var input = {
method : 'put',
returnedContentType : 'application/json',
path : path,
body : {
contentType : 'json; charset=utf-8',
content : params.resource
},
};
return WL.Server.invokeHttp(input);
}
function getProperties(params) {
var resp = {};
for(var index in params.propertyNames){
var name = params.propertyNames[index];
resp[name] = WL.Server.configuration[name];
}
return {"properties" : resp};
}
function getBasePath() {
var si_platform_context=WL.Server.configuration['si.platform.context'];
if (null == si_platform_context || '' == si_platform_context ) {
return 'maximo/oslc/';
}
//WL.Logger.log("++++ worklight property [si.maximo.context]=[" + WL.Server.configuration['si.maximo.context'] + "]");
return si_platform_context + '/oslc/';
}
/**
* Procedures to support query2
*
* @param params
* @returns
*/
function getURLPath(params) {
var path = getBasePath();
path += "os/oslcwodetail/?oslc.pageSize=20&oslc.select="
+ params.oslcSelect;
return path;
}
/**
* Procedure to support query2
*
* @returns {___anonymous4713_4741}
*/
function getSecretData() {
var activeuser = WL.Server.getActiveUser();
var activeuserString = JSON.stringify(activeuser);
WL.Logger.debug("OSLCADAPTER: get secret data - current identity object ="
+ activeuserString);
return {
secretData : '123456'
};
}
// ==================== Authentication Functions =======================//
/**
* TODO: Convert this procedure to java
*
* WL.Logger.debug writes to the WL Server message.log and console.log
*
*/
function query2(params) {
if (null == params || null == params.resource || null == params.queryBase
|| null == params.oslcSelect) {
return {};
}
WL.Logger.debug("OSLC Adapter - query2 :: Entering");
// Attempting to get the session token from the WL getActiveUser API
var activeuser = WL.Server.getActiveUser();
var activeuserString = JSON.stringify(activeuser);
var parsestring = JSON.parse(activeuserString);
var activeusercookies = parsestring["attributes"]["JSESSIONID"];
var stringparams = JSON.stringify(params);
WL.Logger.debug("OSLC ADAPTER: query2 - WL.Server.getActiveUser ["
+ activeuserString + "]");
WL.Logger.debug("OSLC ADAPTER: query2 - activeusercookies ["
+ activeusercookies + "]");
WL.Logger.debug("OSLC ADAPTER: query2 - input string ["
+ stringparams + "]");
// Attempt to get the session token from the Client/device params
var parse2 = JSON.parse(stringparams);
var jsessionidobj = parse2["myjsessionidobj"];
// WL.Logger.debug("OSLC ADAPTER: query2 - input string jsessionidobj [" +
// JSON.stringify(jsessionidobj) + "]");
var token = jsessionidobj.split("=")[1];
var cookie = {
"JSESSIONID" : token
};
WL.Logger.debug("OSLC ADAPTER: query2 - send token ["
+ JSON.stringify(token) + "]");
WL.Logger.debug("OSLC ADAPTER: query2 - send cookie ["
+ JSON.stringify(cookie) + "]");
path = getURLPath(params);
path = encodeURI(path);
WL.Logger.debug("OSLC ADAPTER: query2 - path =[" + path + "]");
var input = {
method : 'get',
returnedContentType : 'application/json',
path : path,
cookies : cookie
};
WL.Logger.debug("OSLC ADAPTER: query2 - send to MAXIMO input ="
+ JSON.stringify(input));
return WL.Server.invokeHttp(input);
}
/**
* Specific function to ping server and get Date from it. Also calculates
* network latency based on before/after datetime when requesting the server
*/
function getServerDate(params) {
WL.Logger.debug("Server clock synchronization::init");
path = getBasePath();
if (path.lastIndexOf('/') == path.length - 1) { // verify if last char is
// '/' , then remove it
path = path.substring(0, path.lastIndexOf("/"));
}
var input = {
method : 'get',
returnedContentType : 'application/json',
path : path,
//cookies : {
// 'JSESSIONID' : params.jsessionid
//},
headers : {
'accept' : 'application/json',
'Cookie' : params.cookie
}
};
WL.Logger.debug("Server clock synchronization::path::" + path);
try {
var befInvoke = Date.parse(new Date().toUTCString());
var response = WL.Server.invokeHttp(input);
var aftInvoke = Date.parse(new Date().toUTCString());
if (response['statusCode'] == 200) {
var srvDate = response['responseHeaders']['Date'];
WL.Logger.debug(srvDate);
return {
beforeInvoke : befInvoke,
afterInvoke : aftInvoke,
serverDate : srvDate
};
}
WL.Logger.debug(response);
return {
isSuccessful : false,
errors : [ response["oslc:Error"] ]
};
} catch (e) {
WL.Logger.debug("Server clock synchronization::Error::" + e);
throw e;
}
}