diff --git a/core/roboconf-dm-rest-commons/src/main/java/net/roboconf/dm/rest/commons/UrlConstants.java b/core/roboconf-dm-rest-commons/src/main/java/net/roboconf/dm/rest/commons/UrlConstants.java index de3549d0..eff86750 100644 --- a/core/roboconf-dm-rest-commons/src/main/java/net/roboconf/dm/rest/commons/UrlConstants.java +++ b/core/roboconf-dm-rest-commons/src/main/java/net/roboconf/dm/rest/commons/UrlConstants.java @@ -37,4 +37,6 @@ public interface UrlConstants { String PREFERENCES = "preferences"; String SCHEDULER = "scheduler"; String AUTHENTICATION = "auth"; + + String SESSION_ID = "sid"; } diff --git a/core/roboconf-dm-rest-commons/src/main/java/net/roboconf/dm/rest/commons/security/AuthenticationManager.java b/core/roboconf-dm-rest-commons/src/main/java/net/roboconf/dm/rest/commons/security/AuthenticationManager.java index d257bc92..7c4e9d57 100644 --- a/core/roboconf-dm-rest-commons/src/main/java/net/roboconf/dm/rest/commons/security/AuthenticationManager.java +++ b/core/roboconf-dm-rest-commons/src/main/java/net/roboconf/dm/rest/commons/security/AuthenticationManager.java @@ -72,6 +72,14 @@ public class AuthenticationManager { private IAuthService authService; + /** + * @author Vincent Zurczak - Linagora + */ + public static enum REST_ROLES { + ADM, TPL_RW, APP_RW, APP_R + } + + /** * Constructor. diff --git a/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/ServletRegistrationComponent.java b/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/ServletRegistrationComponent.java index 161012a9..3ec8389c 100644 --- a/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/ServletRegistrationComponent.java +++ b/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/ServletRegistrationComponent.java @@ -111,6 +111,7 @@ public void starting() throws Exception { this.app.setScheduler( this.scheduler ); this.app.setMavenResolver( this.mavenResolver ); this.app.enableCors( this.enableCors ); + this.app.setAuthenticationManager( this.authenticationMngr ); Dictionary initParams = new Hashtable<> (); initParams.put( "servlet-name", "Roboconf DM (REST)" ); @@ -135,12 +136,17 @@ public void starting() throws Exception { // Register a filter for authentication this.authenticationFilter = new AuthenticationFilter(); this.authenticationFilter.setAuthenticationEnabled( this.enableAuthentication ); - this.authenticationFilter.setAuthenticationMngr( this.authenticationMngr ); + this.authenticationFilter.setAuthenticationManager( this.authenticationMngr ); this.authenticationFilter.setSessionPeriod( this.sessionPeriod ); initParams = new Hashtable<> (); initParams.put( "urlPatterns", "*" ); - this.filterServiceRegistration = this.bundleContext.registerService( Filter.class, this.authenticationFilter, initParams ); + + // Consider the bundle context can be null (e.g. when used outside of OSGi) + if( this.bundleContext != null ) + this.filterServiceRegistration = this.bundleContext.registerService( Filter.class, this.authenticationFilter, initParams ); + else + this.logger.warning( "No bundle context was available, the authentication filter was not registered." ); } @@ -289,7 +295,7 @@ public void setAuthenticationRealm( String authenticationRealm ) { // Propagate the change if( this.authenticationFilter != null ) - this.authenticationFilter.setAuthenticationMngr( this.authenticationMngr ); + this.authenticationFilter.setAuthenticationManager( this.authenticationMngr ); if( this.app != null ) this.app.setAuthenticationManager( this.authenticationMngr ); diff --git a/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/filters/AuthenticationFilter.java b/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/filters/AuthenticationFilter.java index a44a6868..37fd8af8 100644 --- a/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/filters/AuthenticationFilter.java +++ b/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/filters/AuthenticationFilter.java @@ -39,6 +39,7 @@ import javax.servlet.http.HttpServletResponse; import net.roboconf.core.utils.Utils; +import net.roboconf.dm.rest.commons.UrlConstants; import net.roboconf.dm.rest.commons.security.AuthenticationManager; import net.roboconf.dm.rest.services.internal.resources.IAuthenticationResource; @@ -55,7 +56,6 @@ */ public class AuthenticationFilter implements Filter { - public static final String SESSION_ID = "sid"; private final Logger logger = Logger.getLogger( getClass().getName()); private AuthenticationManager authenticationMngr; @@ -81,7 +81,7 @@ public void doFilter( ServletRequest req, ServletResponse resp, FilterChain chai Cookie[] cookies = request.getCookies(); if( cookies != null ) { for( Cookie cookie : cookies ) { - if( SESSION_ID.equals( cookie.getName())) { + if( UrlConstants.SESSION_ID.equals( cookie.getName())) { sessionId = cookie.getValue(); break; } @@ -99,7 +99,7 @@ public void doFilter( ServletRequest req, ServletResponse resp, FilterChain chai // Valid session, go on. Send an error otherwise. // No redirection, we mainly deal with our web socket and REST API. - boolean loginRequest = IAuthenticationResource.LOGIN_PATH.equals( requestedPath ); + boolean loginRequest = requestedPath.endsWith( IAuthenticationResource.PATH + IAuthenticationResource.LOGIN_PATH ); if( loggedIn || loginRequest ) { chain.doFilter( request, response ); } else { @@ -132,7 +132,7 @@ public void setAuthenticationEnabled( boolean authenticationEnabled ) { /** * @param authenticationMngr the authenticationMngr to set */ - public void setAuthenticationMngr( AuthenticationManager authenticationMngr ) { + public void setAuthenticationManager( AuthenticationManager authenticationMngr ) { this.authenticationMngr = authenticationMngr; } diff --git a/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/resources/IAuthenticationResource.java b/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/resources/IAuthenticationResource.java index a8fd4f4f..51407abb 100644 --- a/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/resources/IAuthenticationResource.java +++ b/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/resources/IAuthenticationResource.java @@ -40,7 +40,7 @@ public interface IAuthenticationResource { String PATH = "/" + UrlConstants.AUTHENTICATION; - String LOGIN_PATH = PATH + "/e"; + String LOGIN_PATH = "/e"; /** @@ -67,5 +67,5 @@ public interface IAuthenticationResource { */ @POST @Path("/s") - Response logout( @CookieParam( AuthenticationFilter.SESSION_ID ) String sessionId ); + Response logout( @CookieParam( UrlConstants.SESSION_ID ) String sessionId ); } diff --git a/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/resources/impl/AuthenticationResource.java b/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/resources/impl/AuthenticationResource.java index 0c119341..19d8681a 100644 --- a/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/resources/impl/AuthenticationResource.java +++ b/core/roboconf-dm-rest-services/src/main/java/net/roboconf/dm/rest/services/internal/resources/impl/AuthenticationResource.java @@ -32,8 +32,8 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import net.roboconf.dm.rest.commons.UrlConstants; import net.roboconf.dm.rest.commons.security.AuthenticationManager; -import net.roboconf.dm.rest.services.internal.filters.AuthenticationFilter; import net.roboconf.dm.rest.services.internal.resources.IAuthenticationResource; /** @@ -52,12 +52,18 @@ public Response login( String username, String password ) { String sessionId; Response response; - if( this.authenticationManager == null ) + if( this.authenticationManager == null ) { response = Response.status( Status.INTERNAL_SERVER_ERROR ).entity( "No authentication manager was available." ).build(); - else if(( sessionId = this.authenticationManager.login( username, password )) == null ) + this.logger.fine( "No authentication manager was available. User was " + username ); + + } else if(( sessionId = this.authenticationManager.login( username, password )) == null ) { response = Response.status( Status.FORBIDDEN ).entity( "Authentication failed." ).build(); - else - response = Response.ok().cookie( new NewCookie( AuthenticationFilter.SESSION_ID, sessionId )).build(); + this.logger.fine( "Authentication failed. User was " + username ); + + } else { + response = Response.ok().cookie( new NewCookie( UrlConstants.SESSION_ID, sessionId )).build(); + this.logger.fine( "Authentication succeeded. User was " + username ); + } // NewCookie's implementation uses NewCookie.DEFAULT_MAX_AGE as the default // validity for a cookie, which means it is valid until the browser is closed. diff --git a/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/ServletRegistrationComponentTest.java b/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/ServletRegistrationComponentTest.java index b92a282a..2840eb5a 100644 --- a/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/ServletRegistrationComponentTest.java +++ b/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/ServletRegistrationComponentTest.java @@ -321,7 +321,7 @@ public void testSetAuthenticationRealm() throws Exception { this.register.authenticationFilter = Mockito.mock( AuthenticationFilter.class ); this.register.setAuthenticationRealm( "realm2" ); - Mockito.verify( this.register.authenticationFilter, Mockito.only()).setAuthenticationMngr( Mockito.any( AuthenticationManager.class )); + Mockito.verify( this.register.authenticationFilter, Mockito.only()).setAuthenticationManager( Mockito.any( AuthenticationManager.class )); // Stop... this.register.stopping(); diff --git a/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/filters/AuthenticationFilterTest.java b/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/filters/AuthenticationFilterTest.java index cd80d5aa..9a5a8ff0 100644 --- a/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/filters/AuthenticationFilterTest.java +++ b/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/filters/AuthenticationFilterTest.java @@ -35,6 +35,7 @@ import org.junit.Test; import org.mockito.Mockito; +import net.roboconf.dm.rest.commons.UrlConstants; import net.roboconf.dm.rest.commons.security.AuthenticationManager; import net.roboconf.dm.rest.services.internal.resources.IAuthenticationResource; @@ -76,6 +77,7 @@ public void testDoFiler_withAuthentication_noCookie() throws Exception { filter.setAuthenticationEnabled( true ); HttpServletRequest req = Mockito.mock( HttpServletRequest.class ); + Mockito.when( req.getRequestURI()).thenReturn( "/whatever" ); HttpServletResponse resp = Mockito.mock( HttpServletResponse.class ); FilterChain chain = Mockito.mock( FilterChain.class ); @@ -101,14 +103,15 @@ public void testDoFiler_withAuthentication_withCookie_loggedIn() throws Exceptio AuthenticationManager authMngr = Mockito.mock( AuthenticationManager.class ); Mockito.when( authMngr.isSessionValid( sessionId, sessionPeriod )).thenReturn( true ); - filter.setAuthenticationMngr( authMngr ); + filter.setAuthenticationManager( authMngr ); FilterChain chain = Mockito.mock( FilterChain.class ); HttpServletResponse resp = Mockito.mock( HttpServletResponse.class ); HttpServletRequest req = Mockito.mock( HttpServletRequest.class ); + Mockito.when( req.getRequestURI()).thenReturn( "/whatever" ); Mockito.when( req.getCookies()).thenReturn( new Cookie[] { new Cookie( "as", "as" ), - new Cookie( AuthenticationFilter.SESSION_ID, sessionId ) + new Cookie( UrlConstants.SESSION_ID, sessionId ) }); filter.doFilter( req, resp, chain ); @@ -134,14 +137,15 @@ public void testDoFiler_withAuthentication_withCookie_notLoggedIn() throws Excep AuthenticationManager authMngr = Mockito.mock( AuthenticationManager.class ); Mockito.when( authMngr.isSessionValid( sessionId, sessionPeriod )).thenReturn( false ); - filter.setAuthenticationMngr( authMngr ); + filter.setAuthenticationManager( authMngr ); FilterChain chain = Mockito.mock( FilterChain.class ); HttpServletResponse resp = Mockito.mock( HttpServletResponse.class ); HttpServletRequest req = Mockito.mock( HttpServletRequest.class ); + Mockito.when( req.getRequestURI()).thenReturn( "/whatever" ); Mockito.when( req.getCookies()).thenReturn( new Cookie[] { new Cookie( "as", "as" ), - new Cookie( AuthenticationFilter.SESSION_ID, sessionId ) + new Cookie( UrlConstants.SESSION_ID, sessionId ) }); filter.doFilter( req, resp, chain ); @@ -162,7 +166,7 @@ public void testDoFiler_withAuthentication_noCookie_butLoginPageRequested() thro filter.setAuthenticationEnabled( true ); HttpServletRequest req = Mockito.mock( HttpServletRequest.class ); - Mockito.when( req.getRequestURI()).thenReturn( IAuthenticationResource.LOGIN_PATH ); + Mockito.when( req.getRequestURI()).thenReturn( IAuthenticationResource.PATH + IAuthenticationResource.LOGIN_PATH ); Mockito.when( req.getCookies()).thenReturn( new Cookie[ 0 ]); HttpServletResponse resp = Mockito.mock( HttpServletResponse.class ); diff --git a/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/resources/impl/AuthenticationResourceTest.java b/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/resources/impl/AuthenticationResourceTest.java index a7ddc279..524ec069 100644 --- a/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/resources/impl/AuthenticationResourceTest.java +++ b/core/roboconf-dm-rest-services/src/test/java/net/roboconf/dm/rest/services/internal/resources/impl/AuthenticationResourceTest.java @@ -34,9 +34,9 @@ import org.junit.Test; import org.mockito.Mockito; +import net.roboconf.dm.rest.commons.UrlConstants; import net.roboconf.dm.rest.commons.security.AuthenticationManager; import net.roboconf.dm.rest.commons.security.AuthenticationManager.IAuthService; -import net.roboconf.dm.rest.services.internal.filters.AuthenticationFilter; /** * @author Vincent Zurczak - Linagora @@ -68,7 +68,7 @@ public void testLoginAndLogout() throws Exception { NewCookie cookie = (NewCookie) resp.getMetadata().getFirst( "Set-Cookie" ); Assert.assertNotNull( cookie ); - Assert.assertEquals( AuthenticationFilter.SESSION_ID, cookie.getName()); + Assert.assertEquals( UrlConstants.SESSION_ID, cookie.getName()); Assert.assertNotNull( cookie.getValue()); Assert.assertTrue( authMngr.isSessionValid( cookie.getValue(), -1 )); diff --git a/karaf/roboconf-karaf-dist-dm/src/main/resources/etc/org.ops4j.pax.logging.cfg b/karaf/roboconf-karaf-dist-dm/src/main/resources/etc/org.ops4j.pax.logging.cfg index 3fdd6cee..fc1edfcf 100644 --- a/karaf/roboconf-karaf-dist-dm/src/main/resources/etc/org.ops4j.pax.logging.cfg +++ b/karaf/roboconf-karaf-dist-dm/src/main/resources/etc/org.ops4j.pax.logging.cfg @@ -63,11 +63,11 @@ log4j.appender.jersey.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-32.32c{1 log4j.appender.jersey.file=${karaf.data}/log/jersey.log log4j.appender.jersey.append=true -# Silent very verbose loggers but let them associated with the "roboconf" appender +# Silent very verbose loggers but let them associated with various appenders log4j.logger.net.roboconf.dm.internal.tasks.CheckerForStoredMessagesTask=DEBUG, roboconf log4j.logger.net.roboconf.dm.internal.tasks.CheckerForTargetsConfigurationTask=DEBUG, roboconf log4j.logger.net.roboconf.dm.internal.tasks.CheckerForHeartbeatsTask=DEBUG, roboconf log4j.logger.net.roboconf.dm.rest.services.internal.resources.impl.ApplicationResource=DEBUG, roboconf log4j.logger.net.roboconf.target.api.AbstractThreadedTargetHandler$CheckingRunnable=DEBUG, roboconf log4j.logger.net.roboconf.dm.internal.environment.messaging.DmMessageProcessor=DEBUG, roboconf -log4j.org.apache.karaf.jaas.modules.audit.LogAuditLoginModule=WARN, karaf +log4j.logger.org.apache.karaf.jaas.modules.audit.LogAuditLoginModule=WARN, karaf diff --git a/miscellaneous/roboconf-dm-rest-client/pom.xml b/miscellaneous/roboconf-dm-rest-client/pom.xml index 49432ba2..6a4c948f 100644 --- a/miscellaneous/roboconf-dm-rest-client/pom.xml +++ b/miscellaneous/roboconf-dm-rest-client/pom.xml @@ -170,6 +170,12 @@ 4.3.1 provided + + + org.mockito + mockito-core + test + diff --git a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/WsClient.java b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/WsClient.java index ff8b5a21..2ca0933a 100644 --- a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/WsClient.java +++ b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/WsClient.java @@ -25,6 +25,8 @@ package net.roboconf.dm.rest.client; +import javax.ws.rs.core.Cookie; + import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; @@ -32,11 +34,13 @@ import com.sun.jersey.api.client.config.DefaultClientConfig; import net.roboconf.dm.rest.client.delegates.ApplicationWsDelegate; +import net.roboconf.dm.rest.client.delegates.AuthenticationWsDelegate; import net.roboconf.dm.rest.client.delegates.DebugWsDelegate; import net.roboconf.dm.rest.client.delegates.ManagementWsDelegate; import net.roboconf.dm.rest.client.delegates.PreferencesWsDelegate; import net.roboconf.dm.rest.client.delegates.SchedulerWsDelegate; import net.roboconf.dm.rest.client.delegates.TargetWsDelegate; +import net.roboconf.dm.rest.commons.UrlConstants; import net.roboconf.dm.rest.commons.json.ObjectMapperProvider; /** @@ -80,8 +84,10 @@ public class WsClient { private final TargetWsDelegate targetWsDelegate; private final SchedulerWsDelegate schedulerDelegate; private final PreferencesWsDelegate preferencesWsDelegate; + private final AuthenticationWsDelegate authenticationWsDelegate; private final Client client; + private String sessionId; /** @@ -98,12 +104,13 @@ public WsClient( String rootUrl ) { this.client.setFollowRedirects( true ); WebResource resource = this.client.resource( rootUrl ); - this.applicationDelegate = new ApplicationWsDelegate( resource ); - this.managementDelegate = new ManagementWsDelegate( resource ); - this.debugDelegate = new DebugWsDelegate( resource ); - this.targetWsDelegate = new TargetWsDelegate( resource ); - this.schedulerDelegate = new SchedulerWsDelegate( resource ); - this.preferencesWsDelegate = new PreferencesWsDelegate( resource ); + this.applicationDelegate = new ApplicationWsDelegate( resource, this ); + this.managementDelegate = new ManagementWsDelegate( resource, this ); + this.debugDelegate = new DebugWsDelegate( resource, this ); + this.targetWsDelegate = new TargetWsDelegate( resource, this ); + this.schedulerDelegate = new SchedulerWsDelegate( resource, this ); + this.preferencesWsDelegate = new PreferencesWsDelegate( resource, this ); + this.authenticationWsDelegate = new AuthenticationWsDelegate( resource, this ); } @@ -157,10 +164,48 @@ public PreferencesWsDelegate getPreferencesWsDelegate() { return this.preferencesWsDelegate; } + /** + * @return the authenticationWsDelegate + */ + public AuthenticationWsDelegate getAuthenticationWsDelegate() { + return this.authenticationWsDelegate; + } + /** * @return the Jersey client (useful to configure it) */ public Client getJerseyClient() { return this.client; } + + /** + * Sets the session ID to use when authenticated. + * @param sessionId + */ + public void setSessionId( String sessionId ) { + this.sessionId = sessionId; + } + + /** + * @return the sessionId + */ + public String getSessionId() { + return this.sessionId; + } + + + /** + * @param resource a web resource + * @return a builder with an optional cookie (for authentication) + */ + public WebResource.Builder createBuilder( WebResource resource ) { + + WebResource.Builder result; + if( this.sessionId != null ) + result = resource.cookie( new Cookie( UrlConstants.SESSION_ID, this.sessionId )); + else + result = resource.getRequestBuilder(); + + return result; + } } diff --git a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/ApplicationWsDelegate.java b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/ApplicationWsDelegate.java index 7b36ae35..62f41ccb 100644 --- a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/ApplicationWsDelegate.java +++ b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/ApplicationWsDelegate.java @@ -39,6 +39,7 @@ import net.roboconf.core.model.beans.Component; import net.roboconf.core.model.beans.Instance; import net.roboconf.core.model.beans.Instance.InstanceStatus; +import net.roboconf.dm.rest.client.WsClient; import net.roboconf.dm.rest.client.exceptions.ApplicationWsException; import net.roboconf.dm.rest.commons.UrlConstants; @@ -49,14 +50,17 @@ public class ApplicationWsDelegate { private final WebResource resource; private final Logger logger; + private final WsClient wsClient; /** * Constructor. * @param resource a web resource + * @param the WS client */ - public ApplicationWsDelegate( WebResource resource ) { + public ApplicationWsDelegate( WebResource resource, WsClient wsClient ) { this.resource = resource; + this.wsClient = wsClient; this.logger = Logger.getLogger( getClass().getName()); } @@ -86,7 +90,10 @@ public void changeInstanceState( String applicationName, InstanceStatus newStatu if( newStatus != null ) path = path.queryParam( "new-state", newStatus.toString()); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).post( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .post( ClientResponse.class ); + handleResponse( response ); this.logger.finer( String.valueOf( response.getStatusInfo())); } @@ -104,7 +111,9 @@ public void setDescription( String applicationName, String newDesc ) this.logger.finer( "Updating the description of application " + applicationName + "." ); WebResource path = this.resource.path( UrlConstants.APP ).path( applicationName ).path( "description" ); - ClientResponse response = path.accept( MediaType.TEXT_PLAIN ).post( ClientResponse.class, newDesc ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.TEXT_PLAIN ) + .post( ClientResponse.class, newDesc ); handleResponse( response ); this.logger.finer( String.valueOf( response.getStatusInfo())); @@ -126,7 +135,10 @@ public void deployAndStartAll( String applicationName, String instancePath ) if( instancePath != null ) path = path.queryParam( "instance-path", instancePath ); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).post( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .post( ClientResponse.class ); + handleResponse( response ); this.logger.finer( String.valueOf( response.getStatusInfo())); } @@ -147,7 +159,10 @@ public void stopAll( String applicationName, String instancePath ) if( instancePath != null ) path = path.queryParam( "instance-path", instancePath ); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).post( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .post( ClientResponse.class ); + handleResponse( response ); this.logger.finer( String.valueOf( response.getStatusInfo())); } @@ -168,7 +183,10 @@ public void undeployAll( String applicationName, String instancePath ) if( instancePath != null ) path = path.queryParam( "instance-path", instancePath ); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).post( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .post( ClientResponse.class ); + handleResponse( response ); this.logger.finer( String.valueOf( response.getStatusInfo())); } @@ -192,7 +210,8 @@ public List listChildrenInstances( String applicationName, String inst path = path.queryParam( "instance-path", instancePath ); List result = - path.accept( MediaType.APPLICATION_JSON ) + this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) .type( MediaType.APPLICATION_JSON ) .get( new GenericType> () {}); @@ -221,7 +240,7 @@ public void addInstance( String applicationName, String parentInstancePath, Inst if( parentInstancePath != null ) path = path.queryParam( "instance-path", parentInstancePath ); - ClientResponse response = path + ClientResponse response = this.wsClient.createBuilder( path ) .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON ) .post( ClientResponse.class, instance ); @@ -240,13 +259,13 @@ public void removeInstance( String applicationName, String instancePath ) { this.logger.finer( String.format( "Removing instance \"%s\" from application \"%s\"...", instancePath, applicationName ) ); - this.resource + WebResource path = this.resource .path( UrlConstants.APP ) .path( applicationName ) .path( "instances" ) - .queryParam( "instance-path", instancePath ) - .delete(); + .queryParam( "instance-path", instancePath ); + this.wsClient.createBuilder( path ).delete(); this.logger.finer( String.format( "Instance \"%s\" has been removed from application \"%s\"", instancePath, applicationName ) ); } @@ -260,12 +279,12 @@ public void removeInstance( String applicationName, String instancePath ) { public void resynchronize( String applicationName ) { this.logger.finer( String.format( "Resynchronizing application \"%s\"...", applicationName ) ); - this.resource + WebResource path = this.resource .path( UrlConstants.APP ) .path( applicationName ) - .path( "resynchronize" ) - .post(); + .path( "resynchronize" ); + this.wsClient.createBuilder( path ).post(); this.logger.finer( String.format( "Application \"%s\" has been resynchronized", applicationName ) ); } @@ -278,8 +297,9 @@ public void resynchronize( String applicationName ) { public List listAllComponents( String applicationName ) { this.logger.finer( "Listing components for application " + applicationName + "..." ); - List result = this.resource - .path( UrlConstants.APP ).path( applicationName ).path( "components" ) + WebResource path = this.resource.path( UrlConstants.APP ).path( applicationName ).path( "components" ); + List result = + this.wsClient.createBuilder( path ) .accept( MediaType.APPLICATION_JSON ) .get( new GenericType> () {}); @@ -307,7 +327,10 @@ public List findComponentChildren( String applicationName, String com if( componentName != null ) path = path.queryParam( "component-name", componentName ); - List result = path.accept( MediaType.APPLICATION_JSON ).get( new GenericType> () {}); + List result = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .get( new GenericType> () {}); + if( result != null ) { this.logger.finer( result.size() + " possible children was or were found for " + componentName + "." ); } else { @@ -332,7 +355,10 @@ public List findComponentAncestors( String applicationName, String co if( componentName != null ) path = path.queryParam( "component-name", componentName ); - List result = path.accept( MediaType.APPLICATION_JSON ).get( new GenericType> () {}); + List result = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .get( new GenericType> () {}); + if( result != null ) { this.logger.finer( result.size() + " possible parents was or were found for " + componentName + "." ); } else { @@ -361,7 +387,7 @@ public void bindApplication( String applicationName, String boundTplName, String .queryParam( "bound-tpl", boundTplName ) .queryParam( "bound-app", boundApp ); - ClientResponse response = path.post( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ).post( ClientResponse.class ); handleResponse( response ); } @@ -378,7 +404,10 @@ public List listAllCommands( String applicationName ) { WebResource path = this.resource.path( UrlConstants.APP ) .path( applicationName ).path( "commands" ); - List result = path.accept( MediaType.APPLICATION_JSON ).get( new GenericType> () {}); + List result = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .get( new GenericType> () {}); + if( result != null ) { this.logger.finer( result.size() + " command(s) were found for " + applicationName + "." ); } else { diff --git a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/AuthenticationWsDelegate.java b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/AuthenticationWsDelegate.java new file mode 100644 index 00000000..74385fed --- /dev/null +++ b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/AuthenticationWsDelegate.java @@ -0,0 +1,118 @@ +/** + * Copyright 2017 Linagora, Université Joseph Fourier, Floralis + * + * The present code is developed in the scope of the joint LINAGORA - + * Université Joseph Fourier - Floralis research program and is designated + * as a "Result" pursuant to the terms and conditions of the LINAGORA + * - Université Joseph Fourier - Floralis research program. Each copyright + * holder of Results enumerated here above fully & independently holds complete + * ownership of the complete Intellectual Property rights applicable to the whole + * of said Results, and may freely exploit it in any manner which does not infringe + * the moral rights of the other copyright holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.roboconf.dm.rest.client.delegates; + +import java.util.List; +import java.util.logging.Logger; + +import javax.ws.rs.core.NewCookie; +import javax.ws.rs.core.Response.Status.Family; + +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; + +import net.roboconf.dm.rest.client.WsClient; +import net.roboconf.dm.rest.client.exceptions.DebugWsException; +import net.roboconf.dm.rest.commons.UrlConstants; + +/** + * @author Vincent Zurczak - Linagora + */ +public class AuthenticationWsDelegate { + + private final WebResource resource; + private final WsClient wsClient; + private final Logger logger; + + + /** + * Constructor. + * @param resource a web resource + * @param the WS client + */ + public AuthenticationWsDelegate( WebResource resource, WsClient wsClient ) { + this.resource = resource; + this.wsClient = wsClient; + this.logger = Logger.getLogger( getClass().getName()); + } + + + /** + * Logs in with a user name and a password. + * @param username a user name + * @param password a password + * @return a session ID, or null if login failed + * @throws DebugWsException + */ + public String login( String username, String password ) throws DebugWsException { + + this.logger.finer( "Logging in as " + username ); + WebResource path = this.resource.path( UrlConstants.AUTHENTICATION ).path( "e" ); + ClientResponse response = path + .header( "u", username ) + .header( "p", password ) + .post( ClientResponse.class ); + + if( Family.SUCCESSFUL != response.getStatusInfo().getFamily()) { + String value = response.getEntity( String.class ); + this.logger.finer( response.getStatusInfo() + ": " + value ); + throw new DebugWsException( response.getStatusInfo().getStatusCode(), value ); + } + + // Get the session ID from the cookie that should have been returned + String sessionId = null; + List cookies = response.getCookies(); + if( cookies != null ) { + for( NewCookie cookie : cookies ) { + if( UrlConstants.SESSION_ID.equals( cookie.getName())) { + sessionId = cookie.getValue(); + break; + } + } + } + + // Set the session ID + this.wsClient.setSessionId( sessionId ); + this.logger.finer( "Session ID: " + sessionId ); + + return sessionId; + } + + + /** + * Terminates a session. + * @param sessionId a session ID + * @throws DebugWsException + */ + public void logout( String sessionId ) throws DebugWsException { + + this.logger.finer( "Logging out... Session ID = " + sessionId ); + WebResource path = this.resource.path( UrlConstants.AUTHENTICATION ).path( "s" ); + ClientResponse response = this.wsClient.createBuilder( path ).get( ClientResponse.class ); + this.logger.finer( String.valueOf( response.getStatusInfo())); + this.wsClient.setSessionId( null ); + } +} diff --git a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/DebugWsDelegate.java b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/DebugWsDelegate.java index f098d37e..beca9995 100644 --- a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/DebugWsDelegate.java +++ b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/DebugWsDelegate.java @@ -31,14 +31,15 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response.Status.Family; -import net.roboconf.dm.rest.client.exceptions.DebugWsException; -import net.roboconf.dm.rest.commons.Diagnostic; -import net.roboconf.dm.rest.commons.UrlConstants; - import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.GenericType; import com.sun.jersey.api.client.WebResource; +import net.roboconf.dm.rest.client.WsClient; +import net.roboconf.dm.rest.client.exceptions.DebugWsException; +import net.roboconf.dm.rest.commons.Diagnostic; +import net.roboconf.dm.rest.commons.UrlConstants; + /** * @author Vincent Zurczak - Linagora */ @@ -46,15 +47,17 @@ public class DebugWsDelegate { private final WebResource resource; private final Logger logger; + private final WsClient wsClient; /** * Constructor. - * * @param resource a web resource + * @param the WS client */ - public DebugWsDelegate( WebResource resource ) { + public DebugWsDelegate( WebResource resource, WsClient wsClient ) { this.resource = resource; + this.wsClient = wsClient; this.logger = Logger.getLogger( getClass().getName()); } @@ -73,7 +76,7 @@ public String checkMessagingConnectionForTheDm( String message ) if( message != null ) path = path.queryParam( "message", message ); - ClientResponse response = path.get( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ).get( ClientResponse.class ); if( Family.SUCCESSFUL != response.getStatusInfo().getFamily()) { String value = response.getEntity( String.class ); this.logger.finer( response.getStatusInfo() + ": " + value ); @@ -105,7 +108,7 @@ public String checkMessagingConnectionWithAgent( String applicationName, String if( message != null ) path = path.queryParam( "message", message ); - ClientResponse response = path.get( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ).get( ClientResponse.class ); if( Family.SUCCESSFUL != response.getStatusInfo().getFamily()) { String value = response.getEntity( String.class ); this.logger.finer( response.getStatusInfo() + ": " + value ); @@ -131,7 +134,10 @@ public Diagnostic diagnoseInstance( String applicationName, String instancePath path = path.queryParam( "application-name", applicationName ); path = path.queryParam( "instance-path", instancePath ); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).get( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .get( ClientResponse.class ); + if( Family.SUCCESSFUL != response.getStatusInfo().getFamily()) { String value = response.getEntity( String.class ); this.logger.finer( response.getStatusInfo() + ": " + value ); @@ -153,7 +159,10 @@ public List diagnoseApplication( String applicationName ) { WebResource path = this.resource.path( UrlConstants.DEBUG ).path( "diagnose-application" ); path = path.queryParam( "application-name", applicationName ); - List result = path.accept( MediaType.APPLICATION_JSON ).get( new GenericType> () {}); + List result = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .get( new GenericType> () {}); + if( result == null ) this.logger.finer( "No diagnostic was returned for application " + applicationName ); diff --git a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/ManagementWsDelegate.java b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/ManagementWsDelegate.java index 666e368c..9949ead8 100644 --- a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/ManagementWsDelegate.java +++ b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/ManagementWsDelegate.java @@ -43,6 +43,7 @@ import net.roboconf.core.model.beans.Application; import net.roboconf.core.model.beans.ApplicationTemplate; +import net.roboconf.dm.rest.client.WsClient; import net.roboconf.dm.rest.client.exceptions.ManagementWsException; import net.roboconf.dm.rest.commons.UrlConstants; @@ -53,14 +54,17 @@ public class ManagementWsDelegate { private final WebResource resource; private final Logger logger; + private final WsClient wsClient; /** * Constructor. * @param resource a web resource + * @param the WS client */ - public ManagementWsDelegate( WebResource resource ) { + public ManagementWsDelegate( WebResource resource, WsClient wsClient ) { this.resource = resource; + this.wsClient = wsClient; this.logger = Logger.getLogger( getClass().getName()); } @@ -86,8 +90,8 @@ public void uploadZippedApplicationTemplate( File applicationFile ) throws Manag FormDataMultiPart part = new FormDataMultiPart(); part.bodyPart( new FileDataBodyPart( "file", applicationFile, MediaType.APPLICATION_OCTET_STREAM_TYPE)); - ClientResponse response = this.resource - .path( UrlConstants.APPLICATIONS ).path( "templates" ) + WebResource path = this.resource.path( UrlConstants.APPLICATIONS ).path( "templates" ); + ClientResponse response = this.wsClient.createBuilder( path ) .type( MediaType.MULTIPART_FORM_DATA_TYPE ) .post( ClientResponse.class, part ); @@ -113,7 +117,10 @@ public void loadUnzippedApplicationTemplate( String localFilePath ) throws Manag if( localFilePath != null ) path = path.queryParam( "local-file-path", localFilePath ); - ClientResponse response = path.type( MediaType.APPLICATION_JSON ).post( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .type( MediaType.APPLICATION_JSON ) + .post( ClientResponse.class ); + if( Family.SUCCESSFUL != response.getStatusInfo().getFamily()) { String value = response.getEntity( String.class ); this.logger.finer( response.getStatusInfo() + ": " + value ); @@ -136,7 +143,10 @@ public void loadZippedApplicationTemplate( String url ) throws ManagementWsExcep if( url != null ) path = path.queryParam( "url", url ); - ClientResponse response = path.type( MediaType.APPLICATION_JSON ).post( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .type( MediaType.APPLICATION_JSON ) + .post( ClientResponse.class ); + if( Family.SUCCESSFUL != response.getStatusInfo().getFamily()) { String value = response.getEntity( String.class ); this.logger.finer( response.getStatusInfo() + ": " + value ); @@ -195,7 +205,7 @@ public List listApplicationTemplates( String exactName, Str if( exactQualifier != null ) path = path.queryParam( "qualifier", exactQualifier ); - List result = path + List result = this.wsClient.createBuilder( path ) .accept( MediaType.APPLICATION_JSON ) .get( new GenericType> () {}); @@ -231,11 +241,11 @@ public List listApplicationTemplates() throws ManagementWsE public void deleteApplicationTemplate( String templateName, String templateQualifier ) throws ManagementWsException { this.logger.finer( "Removing application template " + templateName + "..." ); - ClientResponse response = this.resource + WebResource path = this.resource .path( UrlConstants.APPLICATIONS ).path( "templates" ) - .path( templateName ).path( templateQualifier ) - .delete( ClientResponse.class ); + .path( templateName ).path( templateQualifier ); + ClientResponse response = this.wsClient.createBuilder( path ).delete( ClientResponse.class ); String text = response.getEntity( String.class ); this.logger.finer( text ); if( Family.SUCCESSFUL != response.getStatusInfo().getFamily()) @@ -261,8 +271,8 @@ public Application createApplication( String applicationName, String templateNam ApplicationTemplate tpl = new ApplicationTemplate( templateName ).qualifier( templateQualifier ); Application app = new Application( applicationName, tpl ); - ClientResponse response = this.resource - .path( UrlConstants.APPLICATIONS ) + WebResource path = this.resource.path( UrlConstants.APPLICATIONS ); + ClientResponse response = this.wsClient.createBuilder( path ) .type( MediaType.APPLICATION_JSON ) .post( ClientResponse.class, app ); @@ -291,7 +301,7 @@ public List listApplications( String exactName ) throws ManagementW if( exactName != null ) path = path.queryParam( "name", exactName ); - List result = path + List result = this.wsClient.createBuilder( path ) .accept( MediaType.APPLICATION_JSON ) .get( new GenericType> () {}); @@ -326,10 +336,12 @@ public List listApplications() throws ManagementWsException { public void shutdownApplication( String applicationName ) throws ManagementWsException { this.logger.finer( "Removing application " + applicationName + "..." ); - ClientResponse response = this.resource - .path( UrlConstants.APPLICATIONS ).path( applicationName ).path( "shutdown" ) - .post( ClientResponse.class ); + WebResource path = this.resource + .path( UrlConstants.APPLICATIONS ) + .path( applicationName ) + .path( "shutdown" ); + ClientResponse response = this.wsClient.createBuilder( path ).post( ClientResponse.class ); String text = response.getEntity( String.class ); this.logger.finer( text ); if( Family.SUCCESSFUL != response.getStatusInfo().getFamily()) @@ -345,9 +357,8 @@ public void shutdownApplication( String applicationName ) throws ManagementWsExc public void deleteApplication( String applicationName ) throws ManagementWsException { this.logger.finer( "Removing application " + applicationName + "..." ); - ClientResponse response = this.resource - .path( UrlConstants.APPLICATIONS ).path( applicationName ) - .delete( ClientResponse.class ); + WebResource path = this.resource.path( UrlConstants.APPLICATIONS ).path( applicationName ); + ClientResponse response = this.wsClient.createBuilder( path ).delete( ClientResponse.class ); String text = response.getEntity( String.class ); this.logger.finer( text ); diff --git a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/PreferencesWsDelegate.java b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/PreferencesWsDelegate.java index 73bd7404..58096412 100644 --- a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/PreferencesWsDelegate.java +++ b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/PreferencesWsDelegate.java @@ -35,6 +35,7 @@ import com.sun.jersey.api.client.WebResource; import net.roboconf.core.model.runtime.Preference; +import net.roboconf.dm.rest.client.WsClient; import net.roboconf.dm.rest.commons.UrlConstants; /** @@ -44,14 +45,17 @@ public class PreferencesWsDelegate { private final WebResource resource; private final Logger logger; + private final WsClient wsClient; /** * Constructor. * @param resource a web resource + * @param the WS client */ - public PreferencesWsDelegate( WebResource resource ) { + public PreferencesWsDelegate( WebResource resource, WsClient wsClient ) { this.resource = resource; + this.wsClient = wsClient; this.logger = Logger.getLogger( getClass().getName()); } @@ -64,7 +68,7 @@ public List listPreferences() { this.logger.finer( "Getting all the preferences." ); WebResource path = this.resource.path( UrlConstants.PREFERENCES ); - List result = path + List result = this.wsClient.createBuilder( path ) .accept( MediaType.APPLICATION_JSON ) .get( new GenericType> () {}); diff --git a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/SchedulerWsDelegate.java b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/SchedulerWsDelegate.java index b26b06a5..25a6dc46 100644 --- a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/SchedulerWsDelegate.java +++ b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/SchedulerWsDelegate.java @@ -37,6 +37,7 @@ import com.sun.jersey.api.client.WebResource; import net.roboconf.core.model.runtime.ScheduledJob; +import net.roboconf.dm.rest.client.WsClient; import net.roboconf.dm.rest.client.exceptions.SchedulerWsException; import net.roboconf.dm.rest.commons.UrlConstants; import net.roboconf.dm.rest.commons.json.StringWrapper; @@ -48,14 +49,17 @@ public class SchedulerWsDelegate { private final WebResource resource; private final Logger logger; + private final WsClient wsClient; /** * Constructor. * @param resource a web resource + * @param the WS client */ - public SchedulerWsDelegate( WebResource resource ) { + public SchedulerWsDelegate( WebResource resource, WsClient wsClient ) { this.resource = resource; + this.wsClient = wsClient; this.logger = Logger.getLogger( getClass().getName()); } @@ -98,7 +102,8 @@ public List listAllJobs( String appName, String cmdName ) { path = path.queryParam( "cmd-name", cmdName ); List result = - path.accept( MediaType.APPLICATION_JSON ) + this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) .type( MediaType.APPLICATION_JSON ) .get( new GenericType> () {}); @@ -106,7 +111,7 @@ public List listAllJobs( String appName, String cmdName ) { this.logger.finer( result.size() + " jobs were found." ); } else { this.logger.finer( "No scheduled job was found." ); - result = new ArrayList( 0 ); + result = new ArrayList<>( 0 ); } return result; @@ -140,9 +145,11 @@ public String createOrUpdateJob( String jobId, String jobName, String appName, S path = path.queryParam( "cmd-name", cmdName ); path = path.queryParam( "cron", cron ); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).post( ClientResponse.class ); - handleResponse( response ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .post( ClientResponse.class ); + handleResponse( response ); StringWrapper wrapper = response.getEntity( StringWrapper.class ); return wrapper.toString(); } @@ -158,7 +165,10 @@ public void deleteJob( String jobId ) throws SchedulerWsException { this.logger.finer( "Deleting scheduled job: " + jobId ); WebResource path = this.resource.path( UrlConstants.SCHEDULER ).path( jobId ); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).delete( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .delete( ClientResponse.class ); + handleResponse( response ); } @@ -173,9 +183,11 @@ public ScheduledJob getJobProperties( String jobId ) throws SchedulerWsException this.logger.finer( "Getting the properties of a scheduled job: " + jobId ); WebResource path = this.resource.path( UrlConstants.SCHEDULER ).path( jobId ); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).get( ClientResponse.class ); - handleResponse( response ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .get( ClientResponse.class ); + handleResponse( response ); return response.getEntity( ScheduledJob.class ); } diff --git a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/TargetWsDelegate.java b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/TargetWsDelegate.java index 647c12e1..30ae6539 100644 --- a/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/TargetWsDelegate.java +++ b/miscellaneous/roboconf-dm-rest-client/src/main/java/net/roboconf/dm/rest/client/delegates/TargetWsDelegate.java @@ -39,6 +39,7 @@ import net.roboconf.core.model.beans.AbstractApplication; import net.roboconf.core.model.beans.ApplicationTemplate; import net.roboconf.core.model.runtime.TargetWrapperDescriptor; +import net.roboconf.dm.rest.client.WsClient; import net.roboconf.dm.rest.client.exceptions.TargetWsException; import net.roboconf.dm.rest.commons.UrlConstants; @@ -50,14 +51,17 @@ public class TargetWsDelegate { private final WebResource resource; private final Logger logger; + private final WsClient wsClient; /** * Constructor. * @param resource a web resource + * @param the WS client */ - public TargetWsDelegate( WebResource resource ) { + public TargetWsDelegate( WebResource resource, WsClient wsClient ) { this.resource = resource; + this.wsClient = wsClient; this.logger = Logger.getLogger( getClass().getName()); } @@ -71,7 +75,8 @@ public List listAllTargets() { this.logger.finer( "Listing all the available targets." ); WebResource path = this.resource.path( UrlConstants.TARGETS ); List result = - path.accept( MediaType.APPLICATION_JSON ) + this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) .type( MediaType.APPLICATION_JSON ) .get( new GenericType> () {}); @@ -95,7 +100,7 @@ public String createTarget( String targetContent ) throws TargetWsException { this.logger.finer( "Creating a new target." ); WebResource path = this.resource.path( UrlConstants.TARGETS ); - ClientResponse response = path.post( ClientResponse.class, targetContent ); + ClientResponse response = this.wsClient.createBuilder( path ).post( ClientResponse.class, targetContent ); handleResponse( response ); return response.getEntity( String.class ); @@ -112,7 +117,10 @@ public void deleteTarget( String targetId ) throws TargetWsException { this.logger.finer( "Deleting target " + targetId ); WebResource path = this.resource.path( UrlConstants.TARGETS ).path( targetId ); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).delete( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .delete( ClientResponse.class ); + handleResponse( response ); } @@ -144,7 +152,10 @@ public void associateTarget( AbstractApplication app, String instancePathOrCompo if( app instanceof ApplicationTemplate ) path = path.queryParam( "qualifier", ((ApplicationTemplate) app).getQualifier()); - ClientResponse response = path.accept( MediaType.APPLICATION_JSON ).post( ClientResponse.class ); + ClientResponse response = this.wsClient.createBuilder( path ) + .accept( MediaType.APPLICATION_JSON ) + .post( ClientResponse.class ); + handleResponse( response ); } diff --git a/miscellaneous/roboconf-dm-rest-client/src/test/java/net/roboconf/dm/rest/client/delegates/AuthenticationWsDelegateTest.java b/miscellaneous/roboconf-dm-rest-client/src/test/java/net/roboconf/dm/rest/client/delegates/AuthenticationWsDelegateTest.java new file mode 100644 index 00000000..b6f6fe6d --- /dev/null +++ b/miscellaneous/roboconf-dm-rest-client/src/test/java/net/roboconf/dm/rest/client/delegates/AuthenticationWsDelegateTest.java @@ -0,0 +1,105 @@ +/** + * Copyright 2014-2017 Linagora, Université Joseph Fourier, Floralis + * + * The present code is developed in the scope of the joint LINAGORA - + * Université Joseph Fourier - Floralis research program and is designated + * as a "Result" pursuant to the terms and conditions of the LINAGORA + * - Université Joseph Fourier - Floralis research program. Each copyright + * holder of Results enumerated here above fully & independently holds complete + * ownership of the complete Intellectual Property rights applicable to the whole + * of said Results, and may freely exploit it in any manner which does not infringe + * the moral rights of the other copyright holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.roboconf.dm.rest.client.delegates; + +import java.net.URI; + +import javax.security.auth.login.LoginException; +import javax.ws.rs.core.UriBuilder; + +import org.glassfish.grizzly.http.server.HttpServer; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory; + +import net.roboconf.dm.rest.client.WsClient; +import net.roboconf.dm.rest.client.exceptions.DebugWsException; +import net.roboconf.dm.rest.commons.security.AuthenticationManager; +import net.roboconf.dm.rest.commons.security.AuthenticationManager.IAuthService; +import net.roboconf.dm.rest.services.internal.RestApplication; + +/** + * @author Vincent Zurczak - Linagora + */ +public class AuthenticationWsDelegateTest { + + private static final String REST_URI = "http://localhost:8090"; + + private WsClient client; + private HttpServer httpServer; + private IAuthService authService; + + + @After + public void after() { + + if( this.httpServer != null ) + this.httpServer.stop(); + + if( this.client != null ) + this.client.destroy(); + } + + + @Before + public void before() throws Exception { + + URI uri = UriBuilder.fromUri( REST_URI ).build(); + RestApplication restApp = new RestApplication( null ); + + AuthenticationManager authenticationMngr = new AuthenticationManager( "whatever" ); + this.authService = Mockito.mock( IAuthService.class ); + authenticationMngr.setAuthService( this.authService ); + restApp.setAuthenticationManager( authenticationMngr ); + + this.httpServer = GrizzlyServerFactory.createHttpServer( uri, restApp ); + this.client = new WsClient( REST_URI ); + } + + + @Test( expected = DebugWsException.class ) + public void testLogin_failure() throws Exception { + + Mockito.doThrow( new LoginException( "for test" )).when( this.authService ).authenticate( "u", "p" ); + this.client.getAuthenticationWsDelegate().login( "u", "p" ); + } + + + @Test + public void testLogin_success() throws Exception { + + String sessionId = this.client.getAuthenticationWsDelegate().login( "u", "p" ); + Assert.assertNotNull( sessionId ); + this.client.getAuthenticationWsDelegate().logout( sessionId ); + + // Log out twice does not result in any error + this.client.getAuthenticationWsDelegate().logout( sessionId ); + } +} diff --git a/miscellaneous/roboconf-dm-rest-client/src/test/java/net/roboconf/dm/rest/client/delegates/ManagementWsDelegateTest.java b/miscellaneous/roboconf-dm-rest-client/src/test/java/net/roboconf/dm/rest/client/delegates/ManagementWsDelegateTest.java index 62121ad6..5a43b35e 100644 --- a/miscellaneous/roboconf-dm-rest-client/src/test/java/net/roboconf/dm/rest/client/delegates/ManagementWsDelegateTest.java +++ b/miscellaneous/roboconf-dm-rest-client/src/test/java/net/roboconf/dm/rest/client/delegates/ManagementWsDelegateTest.java @@ -152,6 +152,12 @@ public void testListApplications() throws Exception { apps = this.client.getManagementDelegate().listApplications( app.getName() + "0" ); Assert.assertNotNull( apps ); Assert.assertEquals( 0, apps.size()); + + // Get when a session ID was set + this.client.setSessionId( "whatever, filtering is not enabled during these tests" ); + apps = this.client.getManagementDelegate().listApplications(); + Assert.assertNotNull( apps ); + Assert.assertEquals( 1, apps.size()); } diff --git a/miscellaneous/roboconf-integration-tests-dm-with-agents-in-memory/src/test/java/net/roboconf/integration/tests/dm/with/agents/in/memory/RestSecuredServicesTest.java b/miscellaneous/roboconf-integration-tests-dm-with-agents-in-memory/src/test/java/net/roboconf/integration/tests/dm/with/agents/in/memory/RestSecuredServicesTest.java new file mode 100644 index 00000000..72897e5b --- /dev/null +++ b/miscellaneous/roboconf-integration-tests-dm-with-agents-in-memory/src/test/java/net/roboconf/integration/tests/dm/with/agents/in/memory/RestSecuredServicesTest.java @@ -0,0 +1,152 @@ +/** + * Copyright 2014-2017 Linagora, Université Joseph Fourier, Floralis + * + * The present code is developed in the scope of the joint LINAGORA - + * Université Joseph Fourier - Floralis research program and is designated + * as a "Result" pursuant to the terms and conditions of the LINAGORA + * - Université Joseph Fourier - Floralis research program. Each copyright + * holder of Results enumerated here above fully & independently holds complete + * ownership of the complete Intellectual Property rights applicable to the whole + * of said Results, and may freely exploit it in any manner which does not infringe + * the moral rights of the other copyright holders. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.roboconf.integration.tests.dm.with.agents.in.memory; + +import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut; + +import java.io.File; +import java.util.List; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Test; +import org.ops4j.pax.exam.ExamSystem; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.TestContainer; +import org.ops4j.pax.exam.karaf.container.internal.KarafTestContainer; +import org.ops4j.pax.exam.spi.PaxExamRuntime; + +import net.roboconf.core.internal.tests.TestUtils; +import net.roboconf.core.model.beans.ApplicationTemplate; +import net.roboconf.dm.rest.client.WsClient; +import net.roboconf.integration.tests.commons.internal.ItUtils; +import net.roboconf.integration.tests.dm.with.agents.in.memory.probes.DmWithAgentInMemoryTest; +import net.roboconf.messaging.rabbitmq.internal.utils.RabbitMqTestUtils; + +/** + * This test verifies that a client can interact with the DM's REST services. + * @author Vincent Zurczak - Linagora + */ +public class RestSecuredServicesTest extends DmWithAgentInMemoryTest { + + private File karafDirectory; + + + @Override + public Option[] config() throws Exception { + + List