Skip to content

Commit 3e0cf1d

Browse files
committed
#447 New tasks for system plugins, along with mlBundle support
1 parent 1a7faa9 commit 3e0cf1d

File tree

14 files changed

+349
-5
lines changed

14 files changed

+349
-5
lines changed

examples/dependency-project/README.md

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ will be included when the application is deployed:
2727

2828
```
2929
Found mlBundle configuration, will extract all of its dependencies to build/mlBundle
30-
Extracting file: /Users/rrudin/.m2/repository/com/marklogic/example-dependency/1.0.0/example-dependency-1.0.0.jar
3130
[unzip] Expanding: /Users/rrudin/.m2/repository/com/marklogic/example-dependency/1.0.0/example-dependency-1.0.0.jar into /Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/build/mlBundle
3231
Finished extracting mlBundle dependencies
33-
Module paths: [/Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/build/mlBundle/example-dependency/ml-modules, /Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/src/main/ml-modules]
34-
Data paths: [/Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/build/mlBundle/example-dependency/ml-data, /Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/src/main/ml-data]
35-
:mlPrepareBundles (Thread[Task worker for ':' Thread 4,5,main]) completed. Took 0.165 secs.
32+
Module paths including mlBundle paths: [/Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/build/mlBundle/example-dependency/ml-modules, /Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/src/main/ml-modules]
33+
Data paths including mlBundle paths: [/Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/build/mlBundle/example-dependency/ml-data, /Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/src/main/ml-data]
34+
Plugin paths include mlBundle paths: [/Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/build/mlBundle/example-dependency/ml-plugins, /Users/rrudin/dev/workspace/ml-gradle/examples/dependency-project/ml-gradle-client-project/src/main/ml-plugins]
35+
:mlPrepareBundles (Thread[Task worker for ':',5,main]) completed. Took 0.059 secs.
3636
```
3737

3838
And you'll see logging like this that indicates that the example-dependency modules were loaded:
@@ -58,10 +58,37 @@ Shutting down ExecutorService
5858
Writing 2 documents to MarkLogic; port: 8030
5959
```
6060

61+
And also some logging like this that indicates that a system plugin was installed:
62+
63+
```
64+
Writing plugin zip file to URI: /com.marklogic/plugins/varianceplugin.zip
65+
Writing content for /com.marklogic/plugins/varianceplugin.zip
66+
Installing plugin with scope 'native' from URI: /com.marklogic/plugins/varianceplugin.zip
67+
Installed plugin with scope 'native', result: 1
68+
Finished executing command [com.marklogic.appdeployer.command.plugins.InstallPluginsCommand]
69+
```
70+
6171
You can then use qconsole to verify that the following documents were inserted:
6272

6373
- In ml-gradle-client-modules: /example.sjs
64-
- In ml-gradle-client-content: /example/data1.json and /example/data2.json
74+
- In ml-gradle-client-content: /example/data1.json and /example/data2.json (in addition to the data files including
75+
in this project: /testdata/test1.json, /testdata/test2.json, and /testdata/test3.json)
76+
- In Extensions: /native/scope.xml, /native/varianceplugin/libvarianceplugin.dylib, and /native/varianceplugin/manifest.xml
77+
78+
Note that ml-gradle-client-content also contains the plugin zip file at /com.marklogic/plugins/varianceplugin.zip . If
79+
you don't want that to remain, you can use a custom Gradle task to delete it after the deployment, or use the
80+
mlPluginDatabaseName property to store the zip file in a different database.
81+
82+
You can also verify that the plugin was installed correctly by running the following task:
83+
84+
gradle testPlugin
85+
86+
Which should return:
87+
88+
```
89+
> Task :testPlugin
90+
66.6666666666667
91+
```
6592

6693
See [Loading data](https://github.com/marklogic-community/ml-app-deployer/wiki/Loading-data) for more
6794
information on configuring how data is loaded during a deployment.

examples/dependency-project/ml-gradle-client-project/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,8 @@ repositories {
2121
dependencies {
2222
mlBundle "com.marklogic:example-dependency:1.0.0"
2323
}
24+
25+
task testPlugin(type: com.marklogic.gradle.task.ServerEvalTask) {
26+
description = "Run this to verify that the plugin from the example-dependency bundle was installed correctly; should get 66.67 as a result"
27+
javascript = "cts.aggregate('native/varianceplugin', 'variance', cts.elementReference(xs.QName('amount')))"
28+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"database-name": "%%DATABASE%%",
3+
"range-element-index": [
4+
{
5+
"collation": "",
6+
"invalid-values": "reject",
7+
"localname": "amount",
8+
"namespace-uri": "",
9+
"range-value-positions": false,
10+
"scalar-type": "double"
11+
}
12+
]
13+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"amount": 10
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"amount": 20
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"amount": 30
3+
}

examples/dependency-project/provider-project/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ task bundleJar(type: Jar) {
1616
from("src/main/ml-data") {
1717
into("example-dependency/ml-data")
1818
}
19+
from("src/main/ml-plugins") {
20+
into("example-dependency/ml-plugins")
21+
}
1922
destinationDir file("build/libs")
2023
baseName "example-dependency"
2124
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.dylib
2+
*.o
3+
*.zip
4+
manifest.xml
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
PLUGIN_NAME = varianceplugin
2+
PLUGIN_VERSION = 0.1
3+
PLUGIN_PROVIDER = MarkLogic
4+
PLUGIN_DESCRIPTION = variance native plugin
5+
6+
PLUGIN_SRCS = \
7+
VariancePlugin.cpp
8+
9+
MANIFEST = manifest.xml
10+
11+
ZIP_NAME = $(PLUGIN_NAME).zip
12+
PLUGIN_OBJS = ${PLUGIN_SRCS:.cpp=.o}
13+
14+
all:: $(PLUGIN_NAME)
15+
16+
ifneq "$(WINDIR)" ""
17+
18+
-include defs.win32
19+
20+
CPPFLAGS = \
21+
-nologo \
22+
-W3 \
23+
-GR \
24+
-GS- \
25+
-EHsc \
26+
-wd4996 \
27+
-Zi -MTd -bigobj \
28+
-O2 -Oy- \
29+
-D_WIN32_WINNT=0x501 \
30+
-D_SECURE_SCL=0
31+
32+
FULL_LIB_NAME = $(PLUGIN_NAME).dll
33+
34+
DLL_LIBS="$(ProgramW6432)/MarkLogic/MarkLogic.lib"
35+
INCLUDES=-I "$(ProgramW6432)/MarkLogic/include"
36+
37+
$(FULL_LIB_NAME): $(PLUGIN_OBJS)
38+
$(LINK) $(PLUGIN_OBJS) $(DLL_LIBS) \
39+
-nologo -incremental:no -dll -out:$@ -largeaddressaware
40+
41+
%.o: %.cpp
42+
$(CPP) $(CPPFLAGS) $(INCLUDES) -Fo$@ -I. -c $<
43+
44+
vsinstalls: makevcinclude.sh findvcinstalls.cmd
45+
rm -rf $@ vsinstalls
46+
./findvcinstalls.cmd bash ./makevcinclude.sh > $@
47+
48+
clean::
49+
rm -rf $(FULL_LIB_NAME:.dll=.lib)
50+
rm -rf $(FULL_LIB_NAME).manifest
51+
rm -rf $(FULL_LIB_NAME:.dll=.exp)
52+
rm -rf $(FULL_LIB_NAME:.dll=.pdb)
53+
rm -rf ${PLUGIN_SRCS:.cpp=.lib}
54+
rm -rf ${PLUGIN_SRCS:.cpp=.exp}
55+
rm -rf ${PLUGIN_SRCS:.cpp=.pdb}
56+
rm -rf *.pdb
57+
rm -rf vsinstalls
58+
else
59+
60+
ifeq "$(shell uname -s)" "Linux"
61+
MARKLOGIC = /opt/MarkLogic
62+
FULL_LIB_NAME = lib$(PLUGIN_NAME).so
63+
CPP=g++
64+
LIB_FLAGS = -m64 -fPIC -shared
65+
endif
66+
67+
ifeq "$(shell uname -s)" "Darwin"
68+
MARKLOGIC := $(shell cd ~; pwd)/Library/MarkLogic
69+
FULL_LIB_NAME = lib$(PLUGIN_NAME).dylib
70+
CPP=g++
71+
LIB_FLAGS = -m64 -dynamiclib -Wl,-undefined,dynamic_lookup
72+
endif
73+
74+
$(FULL_LIB_NAME): $(PLUGIN_OBJS)
75+
$(CPP) $(LIB_FLAGS) -o $(FULL_LIB_NAME) $(PLUGIN_OBJS)
76+
77+
EXE_EXTRA = -ldl
78+
EXE_FLAGS = -rdynamic
79+
80+
%.o: %.cpp
81+
$(CPP) -m64 -fPIC -g -O2 -Woverloaded-virtual -I. -I$(MARKLOGIC)/include -o $@ -c $<
82+
endif
83+
84+
clean::
85+
rm -rf $(ZIP_NAME)
86+
rm -rf $(FULL_LIB_NAME)
87+
rm -rf $(PLUGIN_OBJS)
88+
rm -rf $(MANIFEST)
89+
90+
$(MANIFEST):
91+
echo '<?xml version="1.0" encoding="UTF-8"?>' > $(MANIFEST)
92+
echo '<plugin xmlns="http://marklogic.com/extension/plugin">' >> $(MANIFEST)
93+
echo ' <name>$(PLUGIN_NAME)</name>' >> $(MANIFEST)
94+
echo ' <id>$(PLUGIN_NAME)</id>' >> $(MANIFEST)
95+
echo ' <version>$(PLUGIN_VERSION)</version>' >> $(MANIFEST)
96+
echo ' <provider-name>$(PLUGIN_PROVIDER)</provider-name>' >> $(MANIFEST)
97+
echo ' <description>$(PLUGIN_DESCRIPTION)</description>' >> $(MANIFEST)
98+
echo ' <native>' >> $(MANIFEST)
99+
echo ' <path>$(FULL_LIB_NAME)</path>' >> $(MANIFEST)
100+
echo ' </native>' >> $(MANIFEST)
101+
echo '</plugin>' >> $(MANIFEST)
102+
103+
$(ZIP_NAME): $(FULL_LIB_NAME) $(MANIFEST)
104+
zip $(ZIP_NAME) $(FULL_LIB_NAME) $(MANIFEST)
105+
106+
$(PLUGIN_NAME): $(ZIP_NAME)
107+
108+
.PHONY: $(PLUGIN_NAME)
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright © 2017 MarkLogic Corporation
3+
*/
4+
5+
#include <MarkLogic.h>
6+
7+
#include <iomanip>
8+
#include <sstream>
9+
#include <string>
10+
#include <vector>
11+
#include <stdio.h>
12+
#include <math.h>
13+
14+
#ifdef _MSC_VER
15+
#define PLUGIN_DLL __declspec(dllexport)
16+
#else // !_MSC_VER
17+
#define PLUGIN_DLL
18+
#endif
19+
20+
using namespace marklogic;
21+
using namespace std;
22+
23+
////////////////////////////////////////////////////////////////////////////////
24+
25+
class Variance : public AggregateUDF
26+
{
27+
public:
28+
struct Value {
29+
double sum, sum_sq, count;
30+
Value() : sum(0), sum_sq(0), count(0) {}
31+
} value;
32+
33+
public:
34+
AggregateUDF* clone() const { return new Variance(*this); }
35+
void close() { delete this; }
36+
37+
void start(Sequence&, Reporter&) {}
38+
void finish(OutputSequence& os, Reporter& reporter);
39+
40+
void map(TupleIterator& values, Reporter& reporter);
41+
void reduce(const AggregateUDF* _o, Reporter& reporter);
42+
43+
void encode(Encoder& e, Reporter& reporter);
44+
void decode(Decoder& d, Reporter& reporter);
45+
46+
protected:
47+
virtual double getResult();
48+
};
49+
50+
double Variance::
51+
getResult()
52+
{
53+
double mean = (value.sum / value.count);
54+
double variance = (value.sum_sq / value.count) - (mean * mean);
55+
56+
// this can be a really small negative number due to floating point
57+
// rounding errors so set to zero if less than zero
58+
if (variance < 0) {
59+
variance = 0;
60+
}
61+
return variance;
62+
}
63+
64+
void Variance::
65+
finish(OutputSequence& os, Reporter& reporter)
66+
{
67+
os.writeValue(getResult());
68+
}
69+
70+
void Variance::
71+
map(TupleIterator& values, Reporter& reporter)
72+
{
73+
for(; !values.done(); values.next()) {
74+
if(!values.null(0)) {
75+
double v; values.value(0,v);
76+
value.sum += v * (double)values.frequency();
77+
value.sum_sq += (v * v) * (double)values.frequency();
78+
value.count += (double)values.frequency();
79+
}
80+
}
81+
}
82+
83+
void Variance::
84+
reduce(const AggregateUDF* _o, Reporter& reporter)
85+
{
86+
const Variance *o = (const Variance*)_o;
87+
value.sum += o->value.sum;
88+
value.sum_sq += o->value.sum_sq;
89+
value.count += o->value.count;
90+
}
91+
92+
void Variance::
93+
encode(Encoder& e, Reporter& reporter)
94+
{
95+
e.encode(&value,sizeof(Value));
96+
}
97+
98+
void Variance::
99+
decode(Decoder& d, Reporter& reporter)
100+
{
101+
d.decode(&value,sizeof(Value));
102+
}
103+
104+
////////////////////////////////////////////////////////////////////////////////
105+
class Stddev : public Variance
106+
{
107+
public:
108+
AggregateUDF* clone() const { return new Stddev(*this); }
109+
110+
protected:
111+
virtual double getResult();
112+
};
113+
114+
double Stddev::
115+
getResult()
116+
{
117+
return sqrt(Variance::getResult());
118+
}
119+
120+
////////////////////////////////////////////////////////////////////////////////
121+
122+
extern "C" PLUGIN_DLL void
123+
marklogicPlugin(Registry& r)
124+
{
125+
r.version();
126+
r.registerAggregate<Variance>("variance");
127+
r.registerAggregate<Stddev>("stddev");
128+
}

0 commit comments

Comments
 (0)