Index: trunk/Dockerfile
===================================================================
--- trunk/Dockerfile	(revision 967)
+++ trunk/Dockerfile	(revision 968)
@@ -2,5 +2,5 @@
 # Base: Ubuntu 18.04 with updates and external packages
 #
-FROM ubuntu:bionic-20200713 AS base
+FROM ubuntu:bionic-20201119 AS base
 ARG DEBIAN_FRONTEND=noninteractive
 ARG BUILD_DEPS=" \
@@ -15,9 +15,10 @@
     libmozjs185-dev \
     libpq5 \
-    libpython2.7 \
+    libpython3.6 \
     libxslt1.1 \
     gdal-bin \
-    python \
+    python3 \
     r-base \
+    python3-pip\
 "
 RUN set -ex \
@@ -54,5 +55,5 @@
     libxml2-dev \
     libxslt1-dev \
-    python-dev \
+    python3-dev \
     uuid-dev \
     r-base-dev \
@@ -68,5 +69,5 @@
     && cd ./zoo-project/zoo-kernel \
     && autoconf \
-    && ./configure --with-python --with-js=/usr --with-mapserver=/usr --with-ms-version=7 --with-json=/usr --with-db-backend --prefix=/usr \
+    && ./configure --with-python=/usr --with-pyvers=3.6 --with-js=/usr --with-mapserver=/usr --with-ms-version=7 --with-json=/usr --with-db-backend --prefix=/usr \
     && make \
     && make install \
@@ -77,4 +78,5 @@
     && cp ../zoo-services/hello-js/cgi-env/* /usr/lib/cgi-bin/ \
     && cp ../zoo-api/js/* /usr/lib/cgi-bin/ \
+    && cp ../zoo-services/utils/open-api/cgi-env/* /usr/lib/cgi-bin/ \
     && cp ../zoo-services/hello-py/cgi-env/* /usr/lib/cgi-bin/ \
     && cp ../zoo-services/hello-js/cgi-env/* /usr/lib/cgi-bin/ \
@@ -112,5 +114,5 @@
 # From zoo-kernel
 COPY --from=builder1 /usr/lib/cgi-bin/ /usr/lib/cgi-bin/
-COPY --from=builder1 /usr/lib/libzoo_service.so.1.5 /usr/lib/libzoo_service.so.1.5
+COPY --from=builder1 /usr/lib/libzoo_service.so.1.8 /usr/lib/libzoo_service.so.1.8
 COPY --from=builder1 /usr/lib/libzoo_service.so /usr/lib/libzoo_service.so
 COPY --from=builder1 /usr/com/zoo-project/ /usr/com/zoo-project/
@@ -146,5 +148,5 @@
 # From zoo-kernel
 COPY --from=builder1 /usr/lib/cgi-bin/ /usr/lib/cgi-bin/
-COPY --from=builder1 /usr/lib/libzoo_service.so.1.5 /usr/lib/libzoo_service.so.1.5
+COPY --from=builder1 /usr/lib/libzoo_service.so.1.8 /usr/lib/libzoo_service.so.1.8
 COPY --from=builder1 /usr/lib/libzoo_service.so /usr/lib/libzoo_service.so
 COPY --from=builder1 /usr/com/zoo-project/ /usr/com/zoo-project/
@@ -159,5 +161,7 @@
     \
     && rm -rf /var/lib/apt/lists/* \
-    && a2enmod cgi
+    && pip3 install Cheetah3 redis\
+    && sed "s:AllowOverride None:AllowOverride All:g" -i /etc/apache2/apache2.conf \
+    && a2enmod cgi rewrite
 
 EXPOSE 80
Index: trunk/docker-compose.yml
===================================================================
--- trunk/docker-compose.yml	(revision 967)
+++ trunk/docker-compose.yml	(revision 968)
@@ -9,6 +9,22 @@
       - ./docker/oas.cfg:/usr/lib/cgi-bin/oas.cfg
       - ./docker/default.conf:/etc/apache2/sites-available/000-default.conf
+      - ./zoo-project/zoo-services/utils/open-api/server/publish.py:/usr/lib/cgi-bin/publish.py
+      - ./zoo-project/zoo-services/utils/open-api/server/subscriber.py:/usr/lib/cgi-bin/subscriber.py
+      - ./docker/.htaccess:/var/www/html/.htaccess
+      - ./zoo-project/zoo-services/utils/open-api/templates/index.html:/var/www/index.html
+      - ./zoo-project/zoo-services/utils/open-api/static:/var/www/html/static
     depends_on:
       - pgbouncer
+    environment:
+      - ZOO_REDIS_HOST=redis
+  websocketd:
+    build: ./docker/websocketd
+    ports:
+      - 8888:8888
+    environment:
+      - ZOO_REDIS_HOST=redis
+    volumes:
+      - ./zoo-project/zoo-services/utils/open-api/server/subscriber.py:/shell.py
+    command: ["--port=8888", "/shell.py"]
   pg:
     image: postgres:9.6.18-alpine
@@ -33,3 +49,4 @@
     depends_on:
       - pg
-
+  redis:
+    image: redis:6.0.9
Index: trunk/docker/main.cfg
===================================================================
--- trunk/docker/main.cfg	(revision 967)
+++ trunk/docker/main.cfg	(revision 968)
@@ -9,4 +9,5 @@
 dataPath = /usr/com/zoo-project
 cacheDir = /tmp/
+templatesPath = /var/www/
 
 [identification]
Index: trunk/docker/oas.cfg
===================================================================
--- trunk/docker/oas.cfg	(revision 967)
+++ trunk/docker/oas.cfg	(revision 968)
@@ -1,23 +1,16 @@
 [openapi]
-rootUrl=http://localhost/cgi-bin/zoo_loader.cgi
+use_content=false
+rootUrl=http://localhost/ogc-api
 links=/,/api,/conformance,/processes
-paths=/root,/api,/conformance,/processes,/processes/{id},/processes/{id}/jobs,/processes/{id}/jobs/{jobID},/processes/{id}/jobs/{jobID}/result
+paths=/root,/api,/conformance,/processes,/processes/{id},/processes/{id}/jobs,/processes/{id}/jobs/{jobID},/processes/{id}/jobs/{jobID}/results
 parameters=id,jobID,resultID
-header_parameters=oas-header1,oas-header2
-version=3.0.1
-
-[oas-header1]
-in=header
-name=Prefer
-type=string
-required=false
-enum=respond-async
-
-[oas-header2]
-in=header
-name=Prefer
-type=string
-required=false
-enum=return=representation,return=minimal
+version=3.0.2
+license_name=OGC license
+license_url=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/LICENSE
+full_html_support=false
+partial_html_support=true
+wsUrl=ws://localhost:8888/
+publisherUrl=http://localhost/cgi-bin/publish.py?jobid=
+io_as_array=true
 
 [/]
@@ -32,10 +25,21 @@
 tags=Home
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/root.yaml
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/LandingPage.yaml
+
+[/index.html]
+rel=alternate
+type=text/html
 
 [/api]
-rel=service
+rel=service-desc
 type=application/openapi+json;version=3.0
 title=the API definition
+
+[/api.html]
+rel=service-doc
+type=text/hml
+
+[api.html]
+href=https://demo.mapmint.com/swagger-ui/ogc-api-processes/
 
 [api]
@@ -50,13 +54,17 @@
 rel=conformance
 type=application/json
-title=WPS 2.0 REST/JSON Binding Extension conformance classes implemented by this server
+title=OGC API - Processes conformance classes implemented by this server
 
 [conformance]
 method=get
 title=information about standards that this API conforms to
-abstract==list all requirements classes specified in a standard (e.g., WPS REST/JSON Binding Core) that the server conforms to
+abstract=list all requirements classes specified in a standard (e.g., WPS REST/JSON Binding Core) that the server conforms to
 tags=Conformance
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/req-classes.yaml
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/ConformanceDeclaration.yaml
+
+[/conformance.html]
+rel=alternate
+type=text/hml
 
 [/processes]
@@ -71,5 +79,9 @@
 tags=GetCapabilities
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/processCollection.yaml
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/ProcessList.yaml
+
+[/processes.html]
+rel=alternate
+type=text/hml
 
 [processes/{id}]
@@ -79,5 +91,6 @@
 tags=ProcessDescription
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/process.yaml
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/ProcessDescription.yaml
+ecode=404
 parameters=/components/parameters/id
 
@@ -95,6 +108,7 @@
 tags=JobList
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/jobCollection.yaml
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/JobList.yaml
 parameters=/components/parameters/id
+ecode=404,500
 method_1=post
 title_1=execute a job
@@ -102,11 +116,14 @@
 tags_1=Execute Endpoint
 tags_description_1=
-schema_1=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/result.yaml
-parameters_1=/components/parameters/id,/components/parameters/oas-header1
+schema_1=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/ExecuteSync.yaml
+parameters_1=/components/parameters/id
+ecode_1=400,404,500
+eschema_1=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/ExecuteAsync.yaml
+ep=,/components/parameters/oas-header1
 
 [requestBody]
 abstract=Mandatory execute request in JSON format
 type=application/json
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/execute.yaml
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/schemas/execute.yaml
 
 [/processes/{id}/jobs/{jobID}]
@@ -116,4 +133,5 @@
 
 [processes/{id}/jobs/{jobID}]
+length=2
 method=get
 title=The status of a job.
@@ -121,13 +139,22 @@
 tags=GetStatus
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/statusInfo.yaml
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/Status.yaml
 parameters=/components/parameters/id,/components/parameters/jobID
-
-[/processes/{id}/jobs/{jobID}/result]
+method_1=delete
+title_1=Cancel a job
+abstract_1=Cancel the job execution.
+tags_1=Dismiss
+tags_description_1=Cencel a job execution
+schema_1=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/Status.yaml
+parameters_1=/components/parameters/id,/components/parameters/jobID
+ecode_1=404,500
+
+
+[/processes/{id}/jobs/{jobID}/results]
 rel=canonical
 type=application/json
 title=Get Result
 
-[processes/{id}/jobs/{jobID}/result]
+[processes/{id}/jobs/{jobID}/results]
 method=get
 title=The result of a job execution.
@@ -135,6 +162,7 @@
 tags=GetResult
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/result.yaml
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/Results.yaml
 parameters=/components/parameters/id,/components/parameters/jobID
+ecode=404,500
 ep=,/components/parameters/oas-header2
 
@@ -150,6 +178,7 @@
 tags=GetResult
 tags_description=
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/valueType.yaml
-parameters=/components/parameters/id,/components/parameters/jobID,/components/parameters/resultID,/components/parameters/oas-header2
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/schemas/valueType.yaml
+parameters=/components/parameters/id,/components/parameters/jobID,/components/parameters/resultID
+ep=,/components/parameters/oas-header2
 
 
@@ -184,14 +213,83 @@
 required=false
 
-[conformTo]
-rootUrl=http://www.opengis.net/spec/WPS/2.0/req/service/binding/rest-json/
+[conformsTo]
+rootUrl=http://www.opengis.net/spec/ogcapi-processes/1.0/conf/
+rootUrl0=http://www.opengis.net/spec/WPS/2.0/req/service/binding/rest-json/
 link=core
 link_1=oas30
 link_2=json
-length=3
+link_3=job-list
+link_4=dismiss
+link_5=callback
+length=6
 
 [exception]
 abstract=Exception
 type=application/json
-schema=https://raw.githubusercontent.com/opengeospatial/wps-rest-binding/master/core/openapi/schemas/exception.yaml
-
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/NotFound.yaml
+default_schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/ServerError.yaml
+
+[responses]
+length=5
+code=404
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/NotFound.yaml
+type=application/json
+title=NotFound
+code_1=500
+schema_1=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/ServerError.yaml
+type_1=application/json
+title_1=ServerError
+code_2=400
+schema_2=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/InvalidParameter.yaml
+type_2=appliction/json
+title_2=InvalidParameter
+code_3=405
+schema_3=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/NotAllowed.yaml
+type_3=appliction/json
+title_3=NotAllowed
+code_4=406
+schema_4=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/responses/NotSupported.yaml
+type_4=appliction/json
+title_4=NotSupported
+
+[callbacks]
+length=3
+state=jobSuccess
+uri=successUri
+schema=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/schemas/result.yaml
+type=application/json
+title=Results received successfully
+state_1=jobInProgress
+uri_1=inProgressUri
+schema_1=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/schemas/statusInfo.yaml
+type_1=application/json
+title_1=Results received successfully
+state_2=jobFailed
+uri_2=failedUrii
+schema_2=https://raw.githubusercontent.com/gfenoy/wps-rest-binding/change-request/95/core/openapi/schemas/exception.yaml
+type_2=application/json
+title_2=Exception received successfully
+
+[links_title]
+self=View this document in JSON.
+alternate=View the alternative version in HTML.
+conformance=View the specifications that the link’s context conforms to.
+service-desc=View the service description.
+service-doc=View service documentation.
+processes=View the list of processes the API offers.
+results=View the results of a process.
+status=View the current status of a job execution.
+execute=View the execution endpoint of a process.
+
+[provider_alt]
+addressDeliveryPoint=streetAddress
+addressCity=addressLocality
+addressAdministrativeArea=addressRegion
+addressPostalCode=postalCode
+addressCountry=addressCountry
+addressElectronicMailAddress=email
+phoneVoice=telephone
+phoneFacsimile=faxNumber
+hoursOfService=hoursAvailable
+contactInstructions=contactOption
+
Index: trunk/docker/websocketd/Dockerfile
===================================================================
--- trunk/docker/websocketd/Dockerfile	(revision 968)
+++ trunk/docker/websocketd/Dockerfile	(revision 968)
@@ -0,0 +1,15 @@
+FROM alpine:3.11
+ADD . /websocketd
+RUN    apk update && apk add --no-cache unzip curl python3 \
+    && if [ ! -e /usr/bin/python ]; then ln -sf python3 /usr/bin/python ; fi \
+    \
+    && echo "**** install pip ****" \
+    && python3 -m ensurepip \
+    && rm -r /usr/lib/python*/ensurepip \
+    && pip3 install --no-cache --upgrade pip setuptools wheel redis \
+    && if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi \
+    && wget -P /tmp/ https://github.com/joewalnes/websocketd/releases/download/v0.3.1/websocketd-0.3.1-linux_amd64.zip \
+    && unzip -o -d /websocketd/ /tmp/websocketd-0.3.1-linux_amd64.zip
+WORKDIR /websocketd
+ENTRYPOINT [ "/websocketd/websocketd" ]
+CMD [ "--port=8888", "/websocketd/shell.sh" ]
Index: trunk/zoo-project/zoo-kernel/configure.ac
===================================================================
--- trunk/zoo-project/zoo-kernel/configure.ac	(revision 967)
+++ trunk/zoo-project/zoo-kernel/configure.ac	(revision 968)
@@ -542,5 +542,5 @@
 
 AC_ARG_WITH([r], 
-	[AS_HELP_STRING([--with-r=PATH], [To enable python support or Specifies an alternative directory for R installation,  disabled by default])], 
+	[AS_HELP_STRING([--with-r=PATH], [To enable R support or Specifies an alternative directory for R installation,  disabled by default])], 
 	[R_PATH="$withval"; R_ENABLED="-DUSE_R"], [R_ENABLED=""])
 
@@ -605,4 +605,5 @@
 	fi
 
+	echo $PYTHONCONFIG
 	# Extract the linker and include flags 
 	PYTHON_LDFLAGS=`$PYTHONCONFIG --ldflags`
Index: trunk/zoo-project/zoo-services/utils/open-api/cgi-env/service.py
===================================================================
--- trunk/zoo-project/zoo-services/utils/open-api/cgi-env/service.py	(revision 967)
+++ trunk/zoo-project/zoo-services/utils/open-api/cgi-env/service.py	(revision 968)
@@ -28,5 +28,5 @@
 def display(conf,inputs,outputs):
     config = configparser.ConfigParser()
-    config.read(conf["lenv"]["cwd"]+'/oas.cfg')
+    config.read(conf["lenv"]["cwd"]+'/oas.cfg',"utf-8")
     nameSpace = {'conf': conf,'inputs': inputs, 'outputs': outputs,"openapi": config}
     t = Template(file=conf["main"]["templatesPath"]+"/index.html",searchList=nameSpace)
Index: trunk/zoo-project/zoo-services/utils/open-api/server/publish.py
===================================================================
--- trunk/zoo-project/zoo-services/utils/open-api/server/publish.py	(revision 967)
+++ trunk/zoo-project/zoo-services/utils/open-api/server/publish.py	(revision 968)
@@ -14,9 +14,14 @@
 
 from urllib import parse
+
 try:
-	params=parse.parse_qs(os.environ["QUERY_STRING"])
-	r = redis.Redis(host='localhost', port=6379, db=0)
-	print(params)
-	r.publish(params["jobid"][0],data)
+    params=parse.parse_qs(os.environ["QUERY_STRING"])
+    r=None
+    if "ZOO_REDIS_HOST" in os.environ:
+        r = redis.Redis(host=os.environ["ZOO_REDIS_HOST"], port=6379, db=0)
+    else:
+        r = redis.Redis(host='redis', port=6379, db=0)
+    print(params)
+    r.publish(params["jobid"][0],data)
 except Exception as e:
 	print(e)
Index: trunk/zoo-project/zoo-services/utils/open-api/server/subscriber.py
===================================================================
--- trunk/zoo-project/zoo-services/utils/open-api/server/subscriber.py	(revision 967)
+++ trunk/zoo-project/zoo-services/utils/open-api/server/subscriber.py	(revision 968)
@@ -11,7 +11,13 @@
 import redis
 import json
+import os
 
 mThreads=[]
-r = redis.Redis(host='localhost', port=6379, db=0)
+r=None
+
+if "ZOO_REDIS_HOST" in os.environ:
+    r = redis.Redis(host=os.environ["ZOO_REDIS_HOST"], port=6379, db=0)
+else:
+    r = redis.Redis(host='redis', port=6379, db=0)
 
 def send(t):
@@ -59,4 +65,4 @@
 
 t0.join()
-for i in range(len(mThreads)):
-    mThreads[i].join()
+#for i in range(len(mThreads)):
+#    mThreads[i].join()
Index: trunk/zoo-project/zoo-services/utils/open-api/static/openapi.js
===================================================================
--- trunk/zoo-project/zoo-services/utils/open-api/static/openapi.js	(revision 967)
+++ trunk/zoo-project/zoo-services/utils/open-api/static/openapi.js	(revision 968)
@@ -108,6 +108,7 @@
     for(var i=0;i < System["JSON_STR"]["outputs"].length;i++){
         var cOutput={};
+	console.log($('input[name="oapi_ioAsArray"]').val()=="true");
 	if($('input[name="oapi_ioAsArray"]').val()=="true")
-	    cOutputs={"id": System["JSON_STR"]["outputs"][i]["id"]};
+	    cOutput={"id": System["JSON_STR"]["outputs"][i]["id"]};
         var cName=System["JSON_STR"]["outputs"][i]["id"].replace(/\./g,"_");
         if(System["JSON_STR"]["outputs"][i]["output"]["formats"]){
