Skip to content

Commit

Permalink
Working installer and static application
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitaeverywhere committed Mar 31, 2017
1 parent 4413475 commit ebfde8c
Show file tree
Hide file tree
Showing 12 changed files with 172 additions and 64 deletions.
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# iKnow Entity Browser<sup>[development]</sup>
# InterSystems iKnow Entity Browser

A visualizer of iKnow entities.
A visualizer of iKnow entities for IntersSystems iKnow on 2016.2+ platforms.

Preview
-------
Expand All @@ -12,6 +12,16 @@ Preview
<img src="https://cloud.githubusercontent.com/assets/4989256/24322376/d1d40878-116b-11e7-98fe-f1b86ff2085a.png" width="430" align="center">
</p>

Installation
------------

Download the latest release and import XML file to Caché (iKnow-enabled namespace). Then, open your
browser at `http://localhost:57772/EntityBrowser/` web page (change the host/port respectively to
your server's addresses and always add the trailing slash `/` at the end of the URL).

To delete the application, simply delete the `EntityBrowser` package, the web application will be
deleted automatically as well as it gets created during installation.

Usage
-----

Expand Down Expand Up @@ -59,7 +69,7 @@ Development

Requires [Node.JS](https://nodejs.org) (v4.0.0-7.5.0+) (but may work on previous versions),
[Git](https://git-scm.com) and
[Caché](http://www.intersystems.com/library/software-downloads/) 2017.1+
[Caché](http://www.intersystems.com/library/software-downloads/) 2016.2+
to be installed.

To install & test, open up a terminal and execute the following set of commands:
Expand All @@ -73,13 +83,12 @@ npm run gulp

Then, open `build/static/index.html` file.

To install the REST client, change the constants in the `import.bat` file and then run the
following:
To install application directly to Caché, modify the constants in the `import.bat` file and then run
it with the following command:

```bash
import
```

This will put `src/cls/EntityBrowser/Router.cls` class into your Caché (change the `import.*`
script), and after you set up a web application, go to configure app settings by clicking setting
button in the top right corner.
This will build the project and put all `src/cls/*` classes into your Caché. Also, this will
export XML file that can be imported to any Caché system (2016.2+).
2 changes: 1 addition & 1 deletion gulpfile.babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const
APP_NAME = `EntityBrowser`,
SOURCE_DIR = `${ __dirname }/src`,
BUILD_DIR = `${ __dirname }/build`,
STATIC_DATA_FILE = `${ SOURCE_DIR }/cls/${ APP_NAME }/REST/StaticData.cls`,
STATIC_DATA_FILE = `${ SOURCE_DIR }/cls/${ APP_NAME }/StaticData.cls`,
context = {
package: pkg
};
Expand Down
28 changes: 17 additions & 11 deletions import.cmd
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
:: This batch script makes the Caché application deployment much faster by building and importing the project.
:: Replace the variables below to match your Caché installation and build & import application to Caché using only one command.

:: Caché 2016.2+ IS REQUIRED TO PROCEED
@echo off

:: CHANGE THIS PATH TO YOUR CACHÉ INSTALLATION PATH ON WINDOWS (folder that contains bin, CSP, mgr and other folders)
:: Configurable variables: change them to fit your system ::
set CACHE_DIR=C:\Program Files\InterSystems\Ensemble
:: NAMESPACE TO IMPORT PACKAGE TO
set NAMESPACE=SAMPLES
:: Other variables
set BUILD_DIR=build\cls
:: set BUILD_STATIC_DIR=build\static
:: set CSP_DIR=C:\Program Files\InterSystems\Ensemble\CSP\samples\EntityBrowser
:: User credentials. Remove if necessary.
set USERNAME=_SYSTEM
set PASSWORD=SYS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

@echo off
:: Pre-configured variables
set BUILD_DIR=build\cls
set XML_EXPORT_DIR=build
set PACKAGE_NAME=EntityBrowser

:: Build and import application to Caché
echo Importing project...
call npm run gulp
:: call xcopy /sy "%~dp0\%BUILD_STATIC_DIR%" "%CSP_DIR%"
(
echo %USERNAME%
echo %PASSWORD%
echo zn "%NAMESPACE%" set st = $system.Status.GetErrorText($system.OBJ.ImportDir("%~dp0%BUILD_DIR%",,"ck",,1^^^)^^^) w "IMPORT STATUS: "_$case(st="",1:"OK",:st^^^), ! halt
echo zn "%NAMESPACE%" set st = $system.Status.GetErrorText($system.OBJ.ImportDir("%~dp0%BUILD_DIR%",,"ck",,1^^^)^^^) w "IMPORT STATUS: "_$case(st="",1:"OK",:st^^^), !
echo s st = $system.Status.GetErrorText($system.OBJ.ExportPackage("%PACKAGE_NAME%", "%~dp0%XML_EXPORT_DIR%\%PACKAGE_NAME%-v"_##class(%PACKAGE_NAME%.Installer^^^).#VERSION_".xml"^^^)^^^) w $c(13,10^^^)_"EXPORT STATUS: "_$case(st="",1:"OK",:st^^^), ! halt
) | "%CACHE_DIR%\bin\cache.exe" -s "%CACHE_DIR%\mgr" -U %NAMESPACE%

:: Other utilities that may be useful:
::
:: Copy files to CSP folder
::$ set BUILD_STATIC_DIR=build\static
::$ set CSP_DIR=C:\Program Files\InterSystems\Ensemble\CSP\samples\EntityBrowser
::$ call xcopy /sy "%~dp0\%BUILD_STATIC_DIR%" "%CSP_DIR%"
31 changes: 15 additions & 16 deletions import.sh
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
#!/usr/bin/env bash
# This batch script makes the Caché application deployment much faster by building and importing the project.
# Replace the variables below to match your Caché installation and build & import application to Caché using only one command.

# Caché 2016.2+ IS REQUIRED TO PROCEED
set +v
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# CHANGE THIS PATH TO YOUR CACHÉ INSTALLATION PATH (folder that contains bin, CSP, mgr and other folders)
# Configurable variables: change them to fit your system #
CACHE_DIR=/InterSystems/Cache
# NAMESPACE TO IMPORT PACKAGE TO
NAMESPACE=SAMPLES
# Other variables
BUILD_DIR=build/cls
BUILD_STATIC_DIR=build/static
CSP_DIR=/InterSystems/Cache/csp/samples/EntityBrowser
# Credentials
USERNAME=_SYSTEM
PASSWORD=SYS
##########################################################

set +v
# Pre-configured variables
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BUILD_DIR=build/cls
XML_EXPORT_DIR=build
PACKAGE_NAME=EntityBrowser

# Build and import application to Caché
echo "Importing project..."
npm run gulp
cp -R "$DIR/$BUILD_STATIC_DIR"* "$CSP_DIR"
cat <<EOT | "$CACHE_DIR/bin/cache" -s "$CACHE_DIR/mgr" -U $NAMESPACE
$USERNAME
$PASSWORD
zn "$NAMESPACE" set st = \$system.Status.GetErrorText(\$system.OBJ.ImportDir("$DIR/$BUILD_DIR",,"ck /checkuptodate=all",,1))
write "IMPORT STATUS: "_\$case(st="",1:"OK",:st), ! halt
cat <<EOT | "$CACHE_DIR/bin/cache" -s "$CACHE_DIR/mgr" -U ${NAMESPACE}
${USERNAME}
${PASSWORD}
zn "${NAMESPACE}" set st = \$system.Status.GetErrorText(\$system.OBJ.ImportDir("${DIR}/${BUILD_DIR}",,"ck /checkuptodate=all",,1))
write "IMPORT STATUS: "_\$case(st="",1:"OK",:st), \!
s st = \$system.Status.GetErrorText(\$system.OBJ.ExportPackage("${PACKAGE_NAME}", "${DIR}/${XML_EXPORT_DIR}/${PACKAGE_NAME}%-v"_##class(${PACKAGE_NAME}.Installer).#VERSION_".xml")) w \$c(13,10)_"EXPORT STATUS: "_\$case(st="",1:"OK",:st), \! halt
EOT
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "iknow-entity-browser",
"version": "0.9.0",
"version": "0.9.1",
"description": "Visualizer for iKnow entities",
"main": "gulpfile.babel.js",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
/// items:
/// type: string
/// </example>
Class EntityBrowser.REST.API Extends (%iKnow.REST.Base, %iKnow.REST.Utils)
Class EntityBrowser.API Extends (%iKnow.REST.Base, %iKnow.REST.Utils)
{

Parameter PAGESIZE = 0;
Expand Down
36 changes: 36 additions & 0 deletions src/cls/EntityBrowser/Installer.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Class EntityBrowser.Installer Extends %Projection.AbstractProjection [ DependsOn = Router ]
{

Projection Reference As Installer;

Parameter AppName = "EntityBrowser";

Parameter DispatchClass = "EntityBrowser.Router";

Parameter VERSION = "<!-- @echo package.version -->";

/// This method is invoked when this class is compiling.
ClassMethod CreateProjection(cls As %String, ByRef params) As %Status
{
write !, "Registering web application /" _ ..#AppName
return ##class(WebAppManager).Register("/" _ ..#AppName, {
"Description": ("A web application for Cache Entity Browser Project. You can change any "
_ "properties of this application except of Dispatch Class property. To delete the "
_ "application simply delete " _ ..#AppName _ " package, the web application will be "
_ "deleted automatically."),
"IsNameSpaceDefault": ($$$NO),
"DispatchClass": (..#DispatchClass)
})
}

/// This method is invoked when a class is 'uncompiled'.
ClassMethod RemoveProjection(cls As %String, ByRef params, recompile As %Boolean) As %Status
{
return:recompile $$$OK
write !, "Removing web application /" _ ..#AppName
return ##class(WebAppManager).Delete("/" _ ..#AppName, {
"DispatchClass": (..#DispatchClass)
})
}

}
13 changes: 0 additions & 13 deletions src/cls/EntityBrowser/REST/Router.cls

This file was deleted.

13 changes: 13 additions & 0 deletions src/cls/EntityBrowser/Router.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/// Application entry point.
Class EntityBrowser.Router Extends (ServeXData, StaticData)
{

XData UrlMap
{
<Routes>
<Map Prefix="/api" Forward="EntityBrowser.API"/>
<Route Url="/(.*)" Method="GET" Call="Serve"/>
</Routes>
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
/// Class that serves the static data encoded in Base64 and stored in this class in XData blocks.
Class EntityBrowser.REST.ServeXData Extends %CSP.REST
/// @author ZitRo
Class EntityBrowser.ServeXData Extends %CSP.REST [ Abstract ]
{

/// This is the <Routes> example. Copy this definitions to the URLMap XData of your class.
XData UrlMap
{
<Routes>
<Map Prefix="/api" Forward="YourAPI.Handler"/>
<Route Url="/(.*)" Method="GET" Call="Serve"/>
</Routes>
}

/// Index file name which will be served when requesting "/".
Parameter IndexFile = "index.html";

Expand All @@ -12,17 +22,10 @@ Parameter CompileTime = {"""" _ $zd($h, 11) _ ", "_ $zdt($NOW(0), 2,1) _ " GMT""
/// Generated in GenerateFiles generator.
Parameter Files As CONFIGVALUE;

/// Copy the <Route> definition to the URLMap XData of your class.
XData UrlMap
{
<Routes>
<Route Url="/(.*)" Method="GET" Call="StaticDelivery"/>
</Routes>
}

/// A generator for Files parameter.
ClassMethod FillFiles() As %Status [ CodeMode = objectgenerator, ForceGenerate ]
ClassMethod FillFiles() As %Status [ CodeMode = objectgenerator ]
{
return:%class.Name="EntityBrowser.ServeXData" $$$OK
set list = $LB()
set (ind, j) = 0
for i=1:1:%compiledclass.XDatas.Count() {
Expand All @@ -38,7 +41,7 @@ ClassMethod FillFiles() As %Status [ CodeMode = objectgenerator, ForceGenerate ]
set $LIST(list, j*2+1) = ""
set $LIST(list, j*2+2) = xd.Name
}
do $system.OBJ.UpdateConfigParam("EntityBrowser.REST.ServeXData", "Files", list)
do $system.OBJ.UpdateConfigParam("EntityBrowser.ServeXData", "Files", list)
return $$$OK
}

Expand All @@ -53,7 +56,7 @@ ClassMethod GetXData(fileName As %String) As %Dictionary.CompiledXData
return ##class(%Dictionary.CompiledXData).%OpenId($ClassName()_"||"_xdn)
}

ClassMethod StaticDelivery(file As %String) As %Status
ClassMethod Serve(file As %String) As %Status
{
set xdata = ..GetXData(file)
return:(xdata = "") ..Http404()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// A class containing static web application.
Class EntityBrowser.REST.StaticData [ GeneratedBy = ExternalTools ]
Class EntityBrowser.StaticData [ GeneratedBy = ExternalTools ]
{

<!-- staticData -->
Expand Down
55 changes: 55 additions & 0 deletions src/cls/EntityBrowser/WebAppManager.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/// This class simplifies work with web applications.
/// For Caché 2016.2+
/// @author ZitRo
Class EntityBrowser.WebAppManager
{

/// Registers new or updates existing web application with new config (as JSON dynamic object).
/// List the properties you can assign to JSON object with the next command:
/// %SYS > do ##class(Security.Applications).Get("/csp/user", .props) zw props
///
/// Usage example: ##class(EntityBrowser.WebAppManager).Register("/name", { "NameSpace": "USER" })
ClassMethod Register(name As %String, config As %DynamicObject = {{}}) As %Status
{
set ns = $Namespace
new $Namespace
try {
set $Namespace = "%SYS"
} catch (e) {
return e.AsSystemError()
}
set st = $$$OK
set spec("AutheEnabled") = $$$AutheCache // defaults
set spec("NameSpace") = ns
set iter = config.%GetIterator()
while iter.%GetNext(.key, .value) {
set spec(key) = value
}
if ('##class(Security.Applications).Exists(name)) {
return ##class(Security.Applications).Create(name, .spec)
}
return ##class(Security.Applications).Modify(name, .spec)
}

/// Deletes the specified application only if it matches matchingConfig.
/// If matchingConfig object is empty, deletes the application. You can specify only those matches
/// you need to check.
ClassMethod Delete(name As %String, matchingConfig As %DynamicObject = {{}})
{
new $Namespace
try {
set $Namespace = "%SYS"
} catch (e) {
return e.AsSystemError()
}
set st = $$$OK
return:'##class(Security.Applications).Exists(name)
do ##class(Security.Applications).Get(name, .spec)
set iter = matchingConfig.%GetIterator()
while iter.%GetNext(.key, .value) {
return:($get(spec(key)) '= value) st
}
return ##class(Security.Applications).Delete(name)
}

}

0 comments on commit ebfde8c

Please sign in to comment.