1 package org
.argeo
.cms
.internal
.runtime
;
3 import static org
.argeo
.api
.cms
.CmsConstants
.CONTEXT_PATH
;
6 import java
.util
.Objects
;
7 import java
.util
.TreeMap
;
8 import java
.util
.concurrent
.CompletableFuture
;
9 import java
.util
.concurrent
.CompletionStage
;
11 import org
.argeo
.api
.cms
.CmsConstants
;
12 import org
.argeo
.api
.cms
.CmsDeployment
;
13 import org
.argeo
.api
.cms
.CmsLog
;
14 import org
.argeo
.api
.cms
.CmsSshd
;
15 import org
.argeo
.api
.cms
.CmsState
;
16 import org
.argeo
.cms
.CmsDeployProperty
;
17 import org
.argeo
.cms
.internal
.http
.CmsAuthenticator
;
18 import org
.argeo
.cms
.internal
.http
.PublicCmsAuthenticator
;
20 import com
.sun
.net
.httpserver
.HttpContext
;
21 import com
.sun
.net
.httpserver
.HttpHandler
;
22 import com
.sun
.net
.httpserver
.HttpServer
;
24 /** Reference implementation of {@link CmsDeployment}. */
25 public class CmsDeploymentImpl
implements CmsDeployment
{
26 private final CmsLog log
= CmsLog
.getLog(getClass());
28 private CmsState cmsState
;
31 private boolean httpExpected
= false;
32 private boolean sshdExpected
= false;
35 private CompletableFuture
<HttpServer
> httpServer
= new CompletableFuture
<>();
36 private Map
<String
, HttpHandler
> httpHandlers
= new TreeMap
<>();
37 private Map
<String
, CmsAuthenticator
> httpAuthenticators
= new TreeMap
<>();
40 private CompletableFuture
<CmsSshd
> cmsSshd
= new CompletableFuture
<>();
43 log
.debug(() -> "CMS deployment available");
49 public void setCmsState(CmsState cmsState
) {
50 this.cmsState
= cmsState
;
52 String httpPort
= this.cmsState
.getDeployProperty(CmsDeployProperty
.HTTP_PORT
.getProperty());
53 String httpsPort
= this.cmsState
.getDeployProperty(CmsDeployProperty
.HTTPS_PORT
.getProperty());
54 httpExpected
= httpPort
!= null || httpsPort
!= null;
56 httpServer
.complete(null);
58 String sshdPort
= this.cmsState
.getDeployProperty(CmsDeployProperty
.SSHD_PORT
.getProperty());
59 sshdExpected
= sshdPort
!= null;
61 cmsSshd
.complete(null);
64 public void setHttpServer(HttpServer httpServer
) {
65 Objects
.requireNonNull(httpServer
);
66 this.httpServer
.complete(httpServer
);
67 // create contexts whose handles had already been published
68 for (String contextPath
: httpHandlers
.keySet()) {
69 HttpHandler httpHandler
= httpHandlers
.get(contextPath
);
70 CmsAuthenticator authenticator
= httpAuthenticators
.get(contextPath
);
71 createHttpContext(contextPath
, httpHandler
, authenticator
);
75 public void addHttpHandler(HttpHandler httpHandler
, Map
<String
, String
> properties
) {
76 final String contextPath
= properties
.get(CONTEXT_PATH
);
77 if (contextPath
== null) {
78 log
.warn("Property " + CONTEXT_PATH
+ " not set on HTTP handler " + properties
+ ". Ignoring it.");
81 boolean isPublic
= Boolean
.parseBoolean(properties
.get(CmsConstants
.CONTEXT_PUBLIC
));
82 CmsAuthenticator authenticator
= isPublic ?
new PublicCmsAuthenticator() : new CmsAuthenticator();
83 httpHandlers
.put(contextPath
, httpHandler
);
84 httpAuthenticators
.put(contextPath
, authenticator
);
85 if (httpServer
.join() == null) {
88 createHttpContext(contextPath
, httpHandler
, authenticator
);
92 public void createHttpContext(String contextPath
, HttpHandler httpHandler
, CmsAuthenticator authenticator
) {
94 if (log
.isTraceEnabled())
95 log
.warn("Ignore HTTP context " + contextPath
+ " as we don't provide an HTTP server");
98 HttpContext httpContext
= httpServer
.join().createContext(contextPath
);
99 // we want to set the authenticator BEFORE the handler actually becomes active
100 httpContext
.setAuthenticator(authenticator
);
101 httpContext
.setHandler(httpHandler
);
102 log
.debug(() -> "Added handler " + contextPath
+ " : " + httpHandler
.getClass().getName());
105 public void removeHttpHandler(HttpHandler httpHandler
, Map
<String
, String
> properties
) {
106 final String contextPath
= properties
.get(CmsConstants
.CONTEXT_PATH
);
107 if (contextPath
== null)
108 return; // ignore silently
109 httpHandlers
.remove(contextPath
);
110 if (httpServer
.join() == null)
112 httpServer
.join().removeContext(contextPath
);
113 log
.debug(() -> "Removed handler " + contextPath
+ " : " + httpHandler
.getClass().getName());
116 public boolean allExpectedServicesAvailable() {
117 if (httpExpected
&& !httpServer
.isDone())
119 if (sshdExpected
&& !cmsSshd
.isDone())
124 public void setCmsSshd(CmsSshd cmsSshd
) {
125 Objects
.requireNonNull(cmsSshd
);
126 this.cmsSshd
.complete(cmsSshd
);
130 public CompletionStage
<HttpServer
> getHttpServer() {
131 return httpServer
.minimalCompletionStage();
135 public CompletionStage
<CmsSshd
> getCmsSshd() {
136 return cmsSshd
.minimalCompletionStage();