Looks like, you do not know about %Installer.Manifest.  You can use it in any different ways, be it installation new application or just simple changing instance's settings. With this manifest I'm building installation archive with project, it includes deployed code some data, and web sources. I'm installing new server with it, manually, or even with docker. And you can use internal Task Manager to run this installation by schedule automatically. You may also look at this project - GitHubCI, it helps to deploy application automatically just after commit to your github repository.

You can look at the documentation here online

and excerpt about custom installation

The Caché installation program allows you to select certain Caché components to be installed on the computer. For example, you may want to install only the Caché SQL Manager. Keep in mind that some selections require that you also install other components.

and about standard installation

The standard installation procedure installs both Caché server and client components on the computer.

I did not show how you made connection to the Caché, and looks like, your Java application has hardcoded login password which used to connect to server. 

so, I may only suggest, that you use code like this

Class.forName ("com.intersys.jdbc.CacheDriver").newInstance();
CacheDataSource ds = new CacheDataSource();
ds.setURL("jdbc:Cache://127.0.0.1:1972/SAMPLES");
Connection dbconn = ds.getConnection("_SYSTEM","SYS");

Last string is Caché login password, so you should use here user's login and password. Any works from your application should be with user's login.

Why do you name it macro ?
Maybe you mean MAC routine ?

I highly recommend to read this tutorial about CacheObjectScript

usually you can call routine by simple command

do ^routine

but sometime you need to call directly to concrete label in that routine

do label^routine()

but in this case if you use curly brace style, you should public such method in routine

label() public {
 write "Hello World!"
​}

or in old style

label()
 write "Hello world!"
 quit

So, you had to start with such explanation.

Well, does not matter what do you set in Accept header, if you don't use it by yourself. Like, you should check incoming content type and send an error if it is not accepted. This Header change nothing in incoming data,  if data was sent in another format.

To read data, you should know that %request has three different ways for getting data. You have already known in %request.Content, which usually contains binary streams. Then %request.MimeData, and %request.Data, it is a Multidimensional properties, and %request has some getters for them, %request.GetMimeData and %request.Get. MimeData, needs when client send data in multipart mime format, such as several files or so on. And %request.Data, in all most cases, and you should look at this property and method %request.Get("somename")

Macro is $$$. Anyway, a little excerpt from documentation  

$
 

Dollar sign (36): Intrinsic (system) function prefix: $name(parameters).

Special variable prefix: $name.

$Znnn (a name beginning with $Z) can be a user-defined function or special variable defined using %ZLANG language extension library. It can also be an intrinsic (InterSystems supplied) function or special variable.

Regular expression end of string anchor; for example, (USA)$.

In ZBREAK debugging, a single-step breakpoint.

As first character at terminal prompt, load interactive subshell.

$$
 

Double dollar sign: Extrinsic (user-written) function prefix: $$name(parameters). $$ is returned by $STACK when context was established by an extrinsic function reference.

Prefix to a routine name to directly invoke that routine.

$$$ Triple dollar sign: Macro invocation prefix.

You should know, that namespace it is a just definition in which databases stored some types of data, and how it mapped.

So, you can only check in which database package stored

write ##class(%SYS.Namespace).GetPackageDest("SAMPLES","%Activate.Enum")
^/opt/cache/mgr/cachelib/

delimited output, first part is a system like in ECP-configuration, and second part is a database path

you can compare this path with default path for packages in this namespace.

w ##class(%SYS.Namespace).GetPackageDest("SAMPLES","")
^/opt/cache/mgr/samples/

Every routines stores directly in database, so, you can't just open it as any file on your filesystem as well as you do it with csp files.

but you can open it with %RoutineMgr class, something like this

USER>zn "samples"

SAMPLES>set rtn=##class(%RoutineMgr).%OpenId("hello.mac")

SAMPLES>while 'rtn.Code.AtEnd { write !,rtn.Code.ReadLine()}
 
hello ; hello world routine
 write !, "hello world"
 write !, "bye"
end quit  ; end
 

if you also need to get list of such files, you can use query StudioOpenDialog in %RoutineMgr class

SAMPLES>set st=##class(%SQL.Statement).%New()
 
SAMPLES>set sc=st.%PrepareClassQuery("%RoutineMgr","StudioOpenDialog")
 
SAMPLES>set rs=st.%Execute("*.mac")
 
SAMPLES>do rs.%Display()
 
 
Dumping result #1
Name    IsDirectory     Type    Size    Date    Description     IconType
DocBook .       9                               0
badroutine.mac          0       62      2004-09-28 13:05:45             0
CinemaData.mac          0       10258   2016-05-10 22:32:04             0
compareloop.mac         0       1201    2004-12-02 18:23:57             0
datent.mac              0       3089    2002-01-03 12:05:01             0
datentobj.mac           0       2627    2002-09-06 00:15:23             0
dbconvert.mac           0       1532    2002-01-03 12:05:52             0
fibonacci.mac           0       365     2002-01-03 12:06:03             0
forexample.mac          0       502     2004-11-30 16:00:08             0
funcexample.mac         0       333     2002-01-03 12:06:30             0
hello.mac               0       251     2016-07-13 12:07:04.520803              0
LDAP.mac                0       68720   2013-12-16 11:48:09.962335              0
lookup.mac              0       8484    2008-08-21 19:17:48             0
lookup1.mac             0       1465    2002-01-03 12:07:15             0
lookup2.mac             0       5984    2002-01-07 18:08:46             0
lookupobj.mac           0       7857    2008-08-21 21:58:25             0
loopend.mac             0       242     2002-01-03 12:08:12             0
loopstart.mac           0       217     2002-01-03 12:08:21             0
nameloop.mac            0       552     2002-01-03 12:08:33             0
passbyref.mac           0       604     2002-01-07 12:01:47             0
postcond.mac            0       341     2002-01-03 12:08:51             0
procexample.mac         0       423     2002-01-03 12:08:59             0
publicvarsexample.mac           0       357     2002-01-03 12:09:09             0
RightTriangle.mac               0       1836    2011-02-24 18:56:29             0
root.mac                0       149     2004-11-30 15:57:29             0
simpleloop.mac          0       161     2002-01-03 12:09:59             0
SQLGatewayTest.mac              0       2480    2016-05-10 22:32:04             0
survivor.mac            0       179     2002-01-03 12:10:32             0
ZAUTHENTICATE.mac               0       37302   2015-03-10 10:48:43.589807              0
ZAUTHORIZE.mac          0       12120   2016-05-10 22:32:04             0
 
30 Rows(s) Affected

but WaitMsg it is on parent's side, my control code ususaly like like this

    set resName="someresource"
    job ..someJob(jobsData,resName)
    set child=$zchild
    
    for {
        set $lb(sc,data)=$system.Event.WaitMsg(resName, 1)
        if sc<=0 {
            quit:'$data(^$Job(child))
        }
        continue:data=""
        // do some staff with incomming data
    }

But if you want to interrupt your child process, of course will be possible only from such process, if your process have some loops you may just check if parent still exists, if not, just stop working.

Steve,

I would recommend to distant webservers from ECP Application servers. In your case I would install webserver exactly on the server where ECP Application Server have already installed, so in this case your connect via superport will be secured, and in this case only web port should be opened in the firewall. Outside of this servers after firewall you need to use some load balancer, in this case I would recommend to use HAProxy. Connection between extarnal HAProxy and  internal webservers could be secured with ssl, but I'm not sure that is really needed.

And in this case it is possible to store all static content such as JS, CSS and images on server where load balancer placed, to avoid redundant request to the data servers. It is not a big problem for the production systems.

So finally in simple view it my looks like below.

Well, you can't write conditions in this way, and compile error which you see, it is actually parsing error for such condition
How you can change it, You should define some function which may do all this check or partially, just return some value for check.

To define such function, you should have your child for Ens.Rule.FunctionSet class, something like this

Class Test.Utils Extends Ens.Rule.FunctionSet
{

ClassMethod GetAt(value As %String = "", index As %String) As %String
{
    if $isobject(value) {
        quit value.GetAt(index)
    }
    quit ""
}

}

and then, you can use it in this way, where GetAt your just created function.

<rule name="">
<constraint name="msgClass" value="Test.TestMessage"></constraint>
<when condition="GetAt(Document.myList,1)=&quot;AA&quot;">
<send transform="" target="DummyOperation"></send>
<return></return>
</when>
</rule>

But your function should return final value for checking, and you can't use write so,

GetAt(Document.myList,1).property1=&quot;AA&quot;