StartToFinish.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /**
  2. Licensed Materials - Property of IBM
  3. IBM Cognos Products: DOCS
  4. (C) Copyright IBM Corp. 2013
  5. US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP
  6. Schedule Contract with IBM Corp.
  7. */
  8. import java.io.BufferedReader;
  9. import java.io.BufferedWriter;
  10. import java.io.File;
  11. import java.io.FileOutputStream;
  12. import java.io.IOException;
  13. import java.io.InputStreamReader;
  14. import java.io.OutputStream;
  15. import java.io.OutputStreamWriter;
  16. import java.net.HttpURLConnection;
  17. import java.net.MalformedURLException;
  18. import java.net.URL;
  19. import com.ibm.json.java.JSONArray;
  20. import com.ibm.json.java.JSONObject;
  21. /**
  22. * This code creates a simple model corresponding to the GOSALES example
  23. * showing sales by product type / product line.
  24. */
  25. public class StartToFinish {
  26. /**
  27. * URL to the server with the FMD SDK installed.
  28. */
  29. final private static String BI_SERVER_URL = "http://localhost:9300/p2pd/servlet/dispatch/";
  30. /**
  31. * The URL part that directs requests to the FMD SDK.
  32. */
  33. final private static String BASE_URL = BI_SERVER_URL + "FmCommand/";
  34. /**
  35. * Path to the model location.
  36. */
  37. final private static String OUTPUT_FILE = "c:/gosales_sdk.fmd";
  38. /**
  39. * POJO code that creates HTTP request passing data in JSON format.
  40. * <p>Should the request return a error or a warning, they are written out to the system error stream.</p>
  41. * @param keyword The URL path segment used to identify the request
  42. * @param method The HTTP method to use ("GET", "POST", "PUT", "DELETE").
  43. * @param json The data to be passed with the request, might be <code>null</code>
  44. * @param modelObjectId The Id of the model object targeted by this request, may be <code>null</code>
  45. * @return The JSON data returned by the SDK. Might be null.
  46. */
  47. static protected JSONObject callFMD(String keyword, String method, JSONObject json, String modelObjectId) {
  48. OutputStream os = null;
  49. BufferedReader br = null;
  50. HttpURLConnection conn = null;
  51. try {
  52. URL url = (modelObjectId == null) ? new URL(BASE_URL + keyword) : new URL(BASE_URL + keyword + "/"+modelObjectId);
  53. conn = (HttpURLConnection) url.openConnection();
  54. conn.setDoOutput(true);
  55. conn.setRequestMethod(method);
  56. // By default, server only allows "GET" and "POST" requests. Use X-header
  57. // to pass other verbs.
  58. if ("GET".equals(method) || "POST".equals(method))
  59. conn.setRequestMethod(method);
  60. else if ("PUT".equals(method) || "DELETE".equals(method)) {
  61. conn.setRequestMethod("POST");
  62. conn.setRequestProperty("X-HTTP-Method-Override", method);
  63. }
  64. conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
  65. if (json != null) {
  66. os = conn.getOutputStream();
  67. os.write(json.serialize().getBytes());
  68. os.flush();
  69. }
  70. br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
  71. String output;
  72. StringBuffer tmp = new StringBuffer();
  73. while ((output = br.readLine()) != null) {
  74. tmp.append(output);
  75. }
  76. JSONObject result = JSONObject.parse(tmp.toString());
  77. JSONArray errorsArray = (JSONArray) result.get("errors");
  78. if (errorsArray != null)
  79. System.err.println("Errors for request \"" + keyword + "\": " + errorsArray.toString());
  80. JSONArray warningsArray = (JSONArray) result.get("warnings");
  81. if (warningsArray != null)
  82. System.err.println("Warnings for request \"" + keyword + "\": " + warningsArray.toString());
  83. return result;
  84. } catch (MalformedURLException e) {
  85. e.printStackTrace();
  86. } catch (IOException e) {
  87. e.printStackTrace();
  88. } finally {
  89. if (json != null)
  90. json.clear();
  91. try {
  92. if (os != null)
  93. os.close();
  94. if (br != null)
  95. br.close();
  96. } catch (IOException e) {
  97. e.printStackTrace();
  98. }
  99. if (conn != null)
  100. conn.disconnect();
  101. }
  102. return null;
  103. }
  104. /**
  105. * Convenience function used to create a model element. See {@link #callFMD(String, String, JSONObject, String)}
  106. * for description of arguments.
  107. * @param keyword The URL path segment used to identify the request
  108. * @param json The data to be passed with the request, might be <code>null</code>
  109. * @return The Id of the model object, if returned by the SDK. Might be null.
  110. */
  111. static protected String fmdCreate(String keyword, JSONObject json) {
  112. JSONObject result = callFMD(keyword, "POST", json, null);
  113. return (String) result.get("id");
  114. }
  115. /**
  116. * A convenience function wrapping "save model to a stream" request.
  117. * @param file The local file in which to save the stream contents
  118. * @param modelObjectId The Id of the model object targeted by this request
  119. * @return <code>true</code> if model was saved successfully
  120. */
  121. static protected boolean saveToFile(File file, String modelObjectId) {
  122. BufferedReader replyReader = null;
  123. HttpURLConnection conn = null;
  124. BufferedWriter fileWriter = null;
  125. try {
  126. URL url = new URL(BASE_URL + "model_save_stream/" + modelObjectId);
  127. conn = (HttpURLConnection) url.openConnection();
  128. conn.setRequestMethod("POST");
  129. conn.setUseCaches(false);
  130. conn.setRequestProperty("Cache-Control", "no-cache");
  131. conn.setRequestProperty("Connection", "Keep-Alive");
  132. conn.setRequestProperty("Content-Type", "text/plain");
  133. replyReader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
  134. String output;
  135. fileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
  136. while ((output = replyReader.readLine()) != null) {
  137. fileWriter.write(output);
  138. fileWriter.newLine();
  139. }
  140. fileWriter.flush();
  141. return true;
  142. } catch (IOException e) {
  143. e.printStackTrace();
  144. } finally {
  145. try {
  146. if (replyReader != null)
  147. replyReader.close();
  148. if (fileWriter != null)
  149. fileWriter.close();
  150. if (conn != null)
  151. conn.disconnect();
  152. } catch (IOException ex) {
  153. ex.printStackTrace();
  154. }
  155. }
  156. return false;
  157. }
  158. /**
  159. * Convenience method creating a pair of a text and locale.
  160. */
  161. static protected JSONArray localizedText(String text, String locale) {
  162. JSONObject tmp = new JSONObject();
  163. tmp.put("text", text);
  164. tmp.put("locale", locale);
  165. JSONArray nameArray = new JSONArray(1);
  166. nameArray.add(tmp);
  167. return nameArray;
  168. }
  169. public static void main(String[] args) throws IOException {
  170. // create model in memory
  171. JSONObject json = new JSONObject();
  172. json.put("name", "Project");
  173. json.put("namespace", "Model");
  174. json.put("locale", "EN");
  175. String modelId = fmdCreate("model_new", json);
  176. // datasource
  177. json.put("parent", modelId);
  178. json.put("name", "great_outdoors_sales");
  179. json.put("cmDataSource", "great_outdoors_sales");
  180. json.put("catalog", "GOSALES");
  181. json.put("schema", "gosales");
  182. json.put("queryType", "relational");
  183. json.put("functionSetId", "V_SQLServer");
  184. json.put("interface", "SS");
  185. String idDataSource = fmdCreate("datasource", json);
  186. // relational dimension
  187. json.put("parent", modelId);
  188. json.put("name", localizedText("Products", "EN"));
  189. String idDimension = fmdCreate("relational_dimension", json);
  190. // level - Line
  191. json.put("parent", idDimension);
  192. json.put("name", localizedText("Line", "EN"));
  193. String idLevel = fmdCreate("level", json);
  194. // query item - Product Line Code
  195. json.put("parent", idLevel);
  196. json.put("name", localizedText("Product Line Code", "EN"));
  197. json.put("usage", "identifier");
  198. json.put("datatype", "int32");
  199. json.put("precision", "10");
  200. json.put("scale", "0");
  201. json.put("isLevelKey", "true");
  202. String idProductLineCode = fmdCreate("query_item", json);
  203. // query item - Product Line
  204. json.put("parent", idLevel);
  205. json.put("name", localizedText("Product Line En", "EN"));
  206. json.put("usage", "identifier");
  207. json.put("datatype", "nVarChar");
  208. json.put("size", "30");
  209. String idProductLine = fmdCreate("query_item", json);
  210. // role
  211. json.put("parent", idProductLine);
  212. json.put("name", localizedText("_memberCaption", "EN"));
  213. fmdCreate("query_item_role", json);
  214. // level - Type
  215. json.put("parent", idDimension);
  216. json.put("name", localizedText("Type", "EN"));
  217. String idTypeLevel = fmdCreate("level", json);
  218. // query item - Product Type Code
  219. json.put("parent", idTypeLevel);
  220. json.put("name", localizedText("Product Type Code", "EN"));
  221. json.put("usage", "identifier");
  222. json.put("datatype", "int32");
  223. json.put("precision", "10");
  224. json.put("scale", "0");
  225. json.put("isLevelKey", "true");
  226. String idProductTypeCode = fmdCreate("query_item", json);
  227. // query item - Product Type Code
  228. json.put("parent", idTypeLevel);
  229. json.put("name", localizedText("Product Type En", "EN"));
  230. json.put("usage", "identifier");
  231. json.put("datatype", "nVarChar");
  232. json.put("size", "40");
  233. String idProductType = fmdCreate("query_item", json);
  234. // role
  235. json.put("parent", idProductType);
  236. json.put("name", localizedText("_memberCaption", "EN"));
  237. fmdCreate("query_item_role", json);
  238. // create relational hierarchy
  239. json.put("parent", idDimension);
  240. json.put("name", localizedText("ByType", "EN"));
  241. json.put("multiRoot", "false");
  242. json.put("rootMember", "All");
  243. json.put("rootCaption", "All");
  244. json.put("isParentChild", "false");
  245. json.put("defaultHierarchy", "true");
  246. // have a level reference
  247. JSONArray jsonLevelRefs = new JSONArray();
  248. jsonLevelRefs.add(idLevel);
  249. jsonLevelRefs.add(idTypeLevel);
  250. json.put("levels", jsonLevelRefs);
  251. fmdCreate("relational_hierarchy", json);
  252. // physical definitions - table PRODUCT_LINE
  253. json.put("parent", idDimension);
  254. json.put("name", "PRODUCT_LINE");
  255. json.put("datasource", idDataSource);
  256. String idTableLine = fmdCreate("physical_table", json);
  257. // physical definitions - table PRODUCT_TYPE
  258. json.put("parent", idDimension);
  259. json.put("name", "PRODUCT_TYPE");
  260. json.put("datasource", idDataSource);
  261. String idTableType = fmdCreate("physical_table", json);
  262. // physical definitions - table PRODUCT
  263. json.put("parent", idDimension);
  264. json.put("name", "PRODUCT");
  265. json.put("datasource", idDataSource);
  266. String idTableProduct = fmdCreate("physical_table", json);
  267. // create a joint with an association PRODUCT_TYPE <-> PRODUCT_LINE
  268. json.put("parent", idDimension);
  269. json.put("name", "FK_PRODUCT_TYPE_PRODUCT_LINE");
  270. json.put("leftTable", idTableLine);
  271. json.put("rightTable", idTableType);
  272. json.put("leftMinCardinality", "one");
  273. json.put("leftMaxCardinality", "one");
  274. json.put("rightMinCardinality", "one");
  275. json.put("rightMaxCardinality", "many");
  276. String idJoin = fmdCreate("physical_join", json);
  277. json.put("parent", idJoin);
  278. json.put("leftColumn", "PRODUCT_LINE_CODE");
  279. json.put("operator", "equals");
  280. json.put("rightColumn", "PRODUCT_LINE_CODE");
  281. fmdCreate("physical_association", json);
  282. // create a joint with an association PRODUCT_TYPE <-> PRODUCT
  283. json.put("parent", idDimension);
  284. json.put("name", "FK_PRODUCT_PRODUCT_TYPE");
  285. json.put("leftTable", idTableType);
  286. json.put("rightTable", idTableProduct);
  287. json.put("leftMinCardinality", "one");
  288. json.put("leftMaxCardinality", "one");
  289. json.put("rightMinCardinality", "one");
  290. json.put("rightMaxCardinality", "many");
  291. String idJoinProduct = fmdCreate("physical_join", json);
  292. json.put("parent", idJoinProduct);
  293. json.put("leftColumn", "PRODUCT_TYPE_CODE");
  294. json.put("operator", "equals");
  295. json.put("rightColumn", "PRODUCT_TYPE_CODE");
  296. fmdCreate("physical_association", json);
  297. // query items mapping - 1
  298. json.put("parent", idDimension);
  299. json.put("columnName", "PRODUCT_LINE_CODE");
  300. json.put("table", idTableLine);
  301. json.put("queryItem", idProductLineCode);
  302. fmdCreate("query_item_mapping", json);
  303. // query items mapping - 2
  304. json.put("parent", idDimension);
  305. json.put("columnName", "PRODUCT_LINE_EN");
  306. json.put("table", idTableLine);
  307. json.put("queryItem", idProductLine);
  308. fmdCreate("query_item_mapping", json);
  309. // query items mapping - 3
  310. json.put("parent", idDimension);
  311. json.put("columnName", "PRODUCT_TYPE_CODE");
  312. json.put("table", idTableType);
  313. json.put("queryItem", idProductTypeCode);
  314. fmdCreate("query_item_mapping", json);
  315. // query items mapping - 4
  316. json.put("parent", idDimension);
  317. json.put("columnName", "PRODUCT_TYPE_EN");
  318. json.put("table", idTableType);
  319. json.put("queryItem", idProductType);
  320. fmdCreate("query_item_mapping", json);
  321. // cube
  322. json.put("parent", modelId);
  323. json.put("name", localizedText("ProductSales", "EN"));
  324. String idCube = fmdCreate("cube", json);
  325. // measure dimension
  326. json.put("parent", idCube);
  327. json.put("name", localizedText("Measures", "EN"));
  328. String idMeasureDimension = fmdCreate("measure_dimension", json);
  329. // measure Quantity
  330. json.put("parent", idMeasureDimension);
  331. json.put("name", localizedText("Quantity", "EN"));
  332. json.put("usage", "fact");
  333. json.put("datatype", "int32");
  334. json.put("precision", "10");
  335. json.put("scale", "0");
  336. json.put("regularAggregate", "sum");
  337. String idMeasure = fmdCreate("measure", json);
  338. // set it as a default measure in the measure dimension
  339. json.put("defaultMeasure", idMeasure);
  340. callFMD("measure_dimension", "PUT", json, idMeasureDimension);
  341. // physical definition - table ORDER_DETAILS
  342. JSONObject tableOrderDetails = new JSONObject();
  343. tableOrderDetails.put("parent", idMeasureDimension);
  344. tableOrderDetails.put("name", "ORDER_DETAILS");
  345. tableOrderDetails.put("datasource", idDataSource);
  346. String idTableOrderDetails = fmdCreate("physical_table", tableOrderDetails);
  347. // physical definition - query item mapping QUANTITY
  348. json.put("parent", idMeasureDimension);
  349. json.put("columnName", "QUANTITY");
  350. json.put("table", idTableOrderDetails);
  351. json.put("queryItem", idMeasure);
  352. fmdCreate("query_item_mapping", json);
  353. // relationship Products<-->Measures
  354. json.put("parent", idCube);
  355. json.put("name", "Products-Measures");
  356. json.put("leftObjectRef", idDimension);
  357. json.put("leftMinCardinality", "one");
  358. json.put("leftMaxCardinality", "one");
  359. json.put("rightObjectRef", idMeasureDimension);
  360. json.put("rightMinCardinality", "one");
  361. json.put("rightMaxCardinality", "many");
  362. JSONArray expressionParts = new JSONArray();
  363. JSONObject part1 = new JSONObject();
  364. part1.put("columnName", "PRODUCT_NUMBER");
  365. part1.put("tableName", "PRODUCT");
  366. part1.put("dataSourceRef", idDataSource);
  367. part1.put("objectRef", idDimension); // relational dimension
  368. expressionParts.add(part1);
  369. expressionParts.add("=");
  370. JSONObject part2 = new JSONObject();
  371. part2.put("columnName", "PRODUCT_NUMBER");
  372. part2.put("tableName", "ORDER_DETAILS");
  373. part2.put("dataSourceRef", idDataSource);
  374. part2.put("objectRef", idMeasureDimension); // measure dimension
  375. expressionParts.add(part2);
  376. json.put("expression", expressionParts);
  377. fmdCreate("relationship", json);
  378. // save model
  379. saveToFile(new File(OUTPUT_FILE), modelId);
  380. // deploy cube
  381. json.put("contentManagerModelPath", "~/folder[@name='My Folders']");
  382. json.put("packageName", "FMDSDKdemo");
  383. json.put("refreshDataSources", "true");
  384. json.put("cube", idCube);
  385. callFMD("cube_deploy", "POST", json, null);
  386. // register cube
  387. json.put("cube", idCube);
  388. callFMD("cube_register", "POST", json, null);
  389. // start the cube
  390. json.put("cube", idCube);
  391. callFMD("cube_start", "POST", json, null);
  392. System.out.println("Cube is ready.");
  393. }
  394. }