diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml index bfe5a9177ba..b1c7c57bcbd 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml @@ -77,7 +77,18 @@ commons-httpclient provided - + + org.wso2.carbon + org.wso2.carbon.base + + + com.googlecode.json-simple.wso2 + json-simple + + + org.wso2.carbon + org.wso2.carbon.user.api + org.wso2.carbon org.wso2.carbon.utils diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationService.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationService.java index f6404de2d65..8a81a8a5ec6 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationService.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationService.java @@ -53,6 +53,11 @@ public interface ApiApplicationRegistrationService { @Consumes(MediaType.APPLICATION_JSON) Response register(RegistrationProfile registrationProfile); + /** + * This method is used to unregister an API application. + * @param applicationName name of the application that needs to be unregistered. + * @return the response status of request. + */ @DELETE Response unregister(@QueryParam("applicationName") String applicationName); } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java index 00f537c0863..7c24b40ffdd 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java @@ -26,6 +26,7 @@ import org.wso2.carbon.apimgt.application.extension.api.util.RegistrationProfile import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants; import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; +import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.apimgt.application.extension.api.util.APIUtil; import org.wso2.carbon.user.api.UserStoreException; @@ -45,13 +46,16 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi @POST public Response register(@PathParam("tenantDomain") String tenantDomain, @QueryParam("applicationName") String applicationName) { - Response response; + String authenticatedTenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + if (authenticatedTenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + return Response.status(Response.Status.NOT_ACCEPTABLE).build(); + } try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); if (PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId() == -1) { String msg = "Invalid tenant domain : " + tenantDomain; - response = Response.status(Response.Status.NOT_ACCEPTABLE).entity(msg).build(); + return Response.status(Response.Status.NOT_ACCEPTABLE).entity(msg).build(); } String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() .getRealmConfiguration().getAdminUserName(); @@ -63,21 +67,19 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi } catch (APIManagerException e) { String msg = "Error occurred while registering an application '" + applicationName + "'"; log.error(msg, e); - response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (UserStoreException e) { String msg = "Failed to retrieve the tenant" + tenantDomain + "'"; log.error(msg, e); - response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } finally { PrivilegedCarbonContext.endTenantFlow(); } - return response; } @Path("register") @POST public Response register(RegistrationProfile registrationProfile) { - Response response; try { String username = APIUtil.getAuthenticatedUser(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); @@ -93,8 +95,9 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD); apiManagementProviderService.registerExistingOAuthApplicationToAPIApplication( jsonStringObject.toJSONString(), registrationProfile.getApplicationName(), - registrationProfile.getConsumerKey(), username, registrationProfile.isAllowedToAllDomains()); - return Response.status(Response.Status.ACCEPTED).entity("OAuth App is mapped as APIM App").build(); + registrationProfile.getConsumerKey(), username, registrationProfile.isAllowedToAllDomains(), + ApiApplicationConstants.DEFAULT_TOKEN_TYPE); + return Response.status(Response.Status.ACCEPTED).entity("true").build(); } else { ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( registrationProfile.getApplicationName(), registrationProfile.getTags(), @@ -103,17 +106,15 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi } } catch (APIManagerException e) { String msg = "Error occurred while registering an application '" - + registrationProfile.getApplicationName() + "'"; + + registrationProfile.getApplicationName() + "'"; log.error(msg, e); - response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("false").build(); } - return response; } @Path("unregister") @DELETE public Response unregister(@QueryParam("applicationName") String applicationName) { - Response response; try { String username = APIUtil.getAuthenticatedUser(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); @@ -122,8 +123,7 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi } catch (APIManagerException e) { String msg = "Error occurred while removing the application '" + applicationName; log.error(msg, e); - response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } - return response; } } \ No newline at end of file diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/permissions.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/permissions.xml index 104c34fe3ee..213141cc67b 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/permissions.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/permissions.xml @@ -30,7 +30,7 @@ Register tenant specific application - /permission/super admin + /device-mgt /register/tenants/* POST super_admin_user diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java index 643d66c23d9..33003b97682 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java @@ -59,7 +59,7 @@ public interface APIManagementProviderService { * Register existing Oauth application as apim application. */ void registerExistingOAuthApplicationToAPIApplication(String jsonString, String applicationName, String clientId, - String username, boolean isAllowedAllDomains) + String username, boolean isAllowedAllDomains, String keyType) throws APIManagerException; /** diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java index 7a2af128d88..8c0e51a7f9c 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java @@ -118,13 +118,47 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe @Override public void registerExistingOAuthApplicationToAPIApplication(String jsonString, String applicationName, String clientId, String username, - boolean isAllowedAllDomains) + boolean isAllowedAllDomains, String keyType) throws APIManagerException { try { APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username); if (apiConsumer != null) { String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain()); - createApplication(apiConsumer, applicationName, username, groupId); + int applicationId = createApplication(apiConsumer, applicationName, username, groupId); + Subscriber subscriber = apiConsumer.getSubscriber(username); + if (subscriber == null) { + String tenantDomain = MultitenantUtils.getTenantDomain(username); + addSubscriber(username, "", groupId, APIManagerUtil.getTenantId(tenantDomain)); + subscriber = apiConsumer.getSubscriber(username); + } + Application[] applications = apiConsumer.getApplications(subscriber, groupId); + Application application = null; + for (Application app : applications) { + if (app.getId() == applicationId) { + application = app; + } + } + if (application == null) { + throw new APIManagerException( + "Api application creation failed for " + applicationName + " to the user " + username); + } + + APIKey retrievedApiApplicationKey = null; + for (APIKey apiKey : application.getKeys()) { + String applicationKeyType = apiKey.getType(); + if (applicationKeyType != null && applicationKeyType.equals(keyType)) { + retrievedApiApplicationKey = apiKey; + break; + } + } + if (retrievedApiApplicationKey != null) { + if (retrievedApiApplicationKey.getConsumerKey().equals(clientId)) { + return; + } else { + throw new APIManagerException("Api application already mapped to another OAuth App"); + } + } + String[] allowedDomains = new String[1]; if (isAllowedAllDomains) { allowedDomains[0] = ApiApplicationConstants.ALLOWED_DOMAINS; @@ -286,14 +320,18 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe try { APIConsumer consumer = APIManagerFactory.getInstance().getAPIConsumer(subscriberName); if (consumer != null) { - Subscriber subscriber = new Subscriber(subscriberName); - subscriber.setSubscribedDate(new Date()); - subscriber.setEmail(subscriberEmail); - subscriber.setTenantId(tenantId); - consumer.addSubscriber(subscriber, groupId); - if (log.isDebugEnabled()) { - log.debug("Successfully created subscriber with name : " + subscriberName + " with groupID : " + - groupId); + synchronized (consumer) { + if (consumer.getSubscriber(subscriberName) == null) { + Subscriber subscriber = new Subscriber(subscriberName); + subscriber.setSubscribedDate(new Date()); + subscriber.setEmail(subscriberEmail); + subscriber.setTenantId(tenantId); + consumer.addSubscriber(subscriber, groupId); + if (log.isDebugEnabled()) { + log.debug("Successfully created subscriber with name : " + subscriberName + + " with groupID : " + groupId); + } + } } } else { throw new APIManagerException("API provider configured for the given API configuration is null. " + @@ -332,8 +370,8 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe if (userVisibleAPIs != null) { Set subscribedAPIs = apiConsumer.getSubscribedAPIs(subscriber, apiApplicationName, groupId); - for (API userVisbleAPI : userVisibleAPIs) { - APIIdentifier apiIdentifier = userVisbleAPI.getId(); + for (API userVisibleAPI : userVisibleAPIs) { + APIIdentifier apiIdentifier = userVisibleAPI.getId(); boolean isSubscribed = false; if (subscribedAPIs != null) { for (SubscribedAPI subscribedAPI : subscribedAPIs) { diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java index dae050d1d79..3ce653c6c87 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java @@ -26,18 +26,22 @@ import org.wso2.carbon.apimgt.api.APIProvider; import org.wso2.carbon.apimgt.api.FaultGatewaysException; import org.wso2.carbon.apimgt.api.model.API; import org.wso2.carbon.apimgt.api.model.APIIdentifier; +import org.wso2.carbon.apimgt.api.model.APIStatus; import org.wso2.carbon.apimgt.api.model.URITemplate; import org.wso2.carbon.apimgt.impl.APIManagerFactory; import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.governance.lcm.util.CommonUtil; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.service.RegistryService; -import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import javax.xml.stream.XMLStreamException; import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; /** * This class represents the concrete implementation of the APIPublisherService that corresponds to providing all @@ -46,83 +50,96 @@ import java.util.List; public class APIPublisherServiceImpl implements APIPublisherService { private static final Log log = LogFactory.getLog(APIPublisherServiceImpl.class); + private static final String PUBLISH_ACTION = "Publish"; - @Override - public void publishAPI(API api) throws APIManagementException, FaultGatewaysException { - if (log.isDebugEnabled()) { - log.debug("Publishing API '" + api.getId() + "'"); - } - try { - String tenantDomain = MultitenantUtils.getTenantDomain(api.getApiOwner()); - int tenantId = - APIPublisherDataHolder.getInstance().getRealmService().getTenantManager().getTenantId(tenantDomain); - // Below code snippet is added load API Lifecycle in tenant mode, where in it does not load when tenant is loaded. - RegistryService registryService = APIPublisherDataHolder.getInstance().getRegistryService(); - CommonUtil.addDefaultLifecyclesIfNotAvailable(registryService.getConfigSystemRegistry(tenantId), - CommonUtil.getRootSystemRegistry(tenantId)); - APIProvider provider = APIManagerFactory.getInstance().getAPIProvider(api.getApiOwner()); - MultitenantUtils.getTenantDomain(api.getApiOwner()); - if (provider != null) { - if (!provider.isAPIAvailable(api.getId())) { - provider.addAPI(api); - log.info("Successfully published API '" + api.getId().getApiName() + "' with context '" + - api.getContext() + "' and version '" + api.getId().getVersion() + "'"); - } else { - provider.updateAPI(api); - log.info("An API already exists with the name '" + api.getId().getApiName() + "', context '" + - api.getContext() + "' and version '" + api.getId().getVersion() + - "'. Thus, the API config is updated"); - } - provider.saveSwagger20Definition(api.getId(), createSwaggerDefinition(api)); - } else { - throw new APIManagementException("API provider configured for the given API configuration is null. " + - "Thus, the API is not published"); - } - } catch (UserStoreException e) { - throw new APIManagementException("Failed to get the tenant id for the user " + api.getApiOwner(), e); - } catch (FileNotFoundException e) { - throw new APIManagementException("Failed to retrieve life cycle file ", e); - } catch (RegistryException e) { - throw new APIManagementException("Failed to access the registry ", e); - } catch (XMLStreamException e) { - throw new APIManagementException("Failed parsing the lifecycle xml.", e); - } - } - - private String createSwaggerDefinition(API api) { - //{"paths":{"/controller/*":{"get":{"responses":{"200":{}}}},"/manager/*":{"get":{"responses":{"200":{}}}}}, - // "swagger":"2.0","info":{"title":"RaspberryPi","version":"1.0.0"}} - JsonObject swaggerDefinition = new JsonObject(); + @Override + public void publishAPI(final API api) throws APIManagementException, FaultGatewaysException { + String tenantDomain = MultitenantUtils.getTenantDomain(api.getApiOwner()); + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); + try { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + // Below code snippet is added to load API Lifecycle in tenant mode. + RegistryService registryService = APIPublisherDataHolder.getInstance().getRegistryService(); + CommonUtil.addDefaultLifecyclesIfNotAvailable(registryService.getConfigSystemRegistry(tenantId), + CommonUtil.getRootSystemRegistry(tenantId)); + APIProvider provider = APIManagerFactory.getInstance().getAPIProvider(api.getApiOwner()); + MultitenantUtils.getTenantDomain(api.getApiOwner()); + if (provider != null) { + if (provider.isDuplicateContextTemplate(api.getContext())) { + throw new APIManagementException( + "Error occurred while adding the API. A duplicate API" + + " context already exists for " + api.getContext()); + } + if (!provider.isAPIAvailable(api.getId())) { + provider.addAPI(api); + provider.changeLifeCycleStatus(api.getId(), PUBLISH_ACTION); + if (log.isDebugEnabled()) { + log.debug("Successfully published API '" + api.getId().getApiName() + + "' with context '" + api.getContext() + "' and version '" + + api.getId().getVersion() + "'"); + } + } else { + api.setStatus(APIStatus.PUBLISHED); + provider.updateAPI(api); + if (log.isDebugEnabled()) { + log.debug("An API already exists with the name '" + api.getId().getApiName() + + "', context '" + api.getContext() + "' and version '" + + api.getId().getVersion() + "'. Thus, the API config is updated"); + } + } + provider.saveSwagger20Definition(api.getId(), createSwaggerDefinition(api)); + } else { + throw new APIManagementException("API provider configured for the given API configuration " + + "is null. Thus, the API is not published"); + } + } catch (FileNotFoundException e) { + throw new APIManagementException("Failed to retrieve life cycle file ", e); + } catch (RegistryException e) { + throw new APIManagementException("Failed to access the registry ", e); + } catch (XMLStreamException e) { + throw new APIManagementException("Failed parsing the lifecycle xml.", e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } - JsonObject paths = new JsonObject(); - for (URITemplate uriTemplate : api.getUriTemplates()) { - JsonObject response = new JsonObject(); - response.addProperty("200", ""); + private String createSwaggerDefinition(API api) { + Map httpVerbsMap = new HashMap<>(); - JsonObject responses = new JsonObject(); - responses.add("responses", response); + for (URITemplate uriTemplate : api.getUriTemplates()) { + JsonObject response = new JsonObject(); + response.addProperty("200", ""); - JsonObject httpVerb = new JsonObject(); - httpVerb.add(uriTemplate.getHTTPVerb().toLowerCase(), responses); + JsonObject responses = new JsonObject(); + responses.add("responses", response); + JsonObject httpVerbs = httpVerbsMap.get(uriTemplate.getUriTemplate()); + if (httpVerbs == null) { + httpVerbs = new JsonObject(); + } + httpVerbs.add(uriTemplate.getHTTPVerb().toLowerCase(), responses); + httpVerbsMap.put(uriTemplate.getUriTemplate(), httpVerbs); + } - JsonObject path = new JsonObject(); - path.add(uriTemplate.getUriTemplate(), httpVerb); + Iterator it = httpVerbsMap.entrySet().iterator(); + JsonObject paths = new JsonObject(); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry) it.next(); + paths.add(pair.getKey(), pair.getValue()); + it.remove(); + } - paths.add(uriTemplate.getUriTemplate(), httpVerb); - } - swaggerDefinition.add("paths", paths); - swaggerDefinition.addProperty("swagger", "2.0"); + JsonObject info = new JsonObject(); + info.addProperty("title", api.getId().getApiName()); + info.addProperty("version", api.getId().getVersion()); - JsonObject info = new JsonObject(); - info.addProperty("title", api.getId().getApiName()); - info.addProperty("version", api.getId().getVersion()); - swaggerDefinition.add("info", info); + JsonObject swaggerDefinition = new JsonObject(); + swaggerDefinition.add("paths", paths); + swaggerDefinition.addProperty("swagger", "2.0"); + swaggerDefinition.add("info", info); - return swaggerDefinition.toString(); - //return "{\"paths\":{\"/controller/*\":{\"get\":{\"responses\":{\"200\":{}}}}, - // \"/manager/*\":{\"get\":{\"responses\":{\"200\":{}}}}},\"swagger\":\"2.0\", - // \"info\":{\"title\":\"RaspberryPi\",\"version\":\"1.0.0\"}}"; - } + return swaggerDefinition.toString(); + } @Override public void removeAPI(APIIdentifier id) throws APIManagementException { diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java index 2a502825adc..9ae9340513f 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java @@ -37,6 +37,7 @@ public class APIPublisherUtil { private static final String DEFAULT_API_VERSION = "1.0.0"; public static final String API_VERSION_PARAM="{version}"; + public static final String API_PUBLISH_ENVIRONEMENT = "Production and Sandbox"; enum HTTPMethod { GET, POST, DELETE, PUT, OPTIONS @@ -75,10 +76,13 @@ public class APIPublisherUtil { api.setUrl(config.getEndpoint()); api.addAvailableTiers(provider.getTiers()); api.setEndpointSecured(true); - api.setStatus(APIStatus.PUBLISHED); + api.setStatus(APIStatus.CREATED); api.setTransports(config.getTransports()); api.setContextTemplate(config.getContextTemplate()); api.setUriTemplates(config.getUriTemplates()); + Set environements = new HashSet<>(); + environements.add(API_PUBLISH_ENVIRONEMENT); + api.setEnvironments(environements); Set tiers = new HashSet(); tiers.add(new Tier(APIConstants.UNLIMITED_TIER)); api.addAvailableTiers(tiers); @@ -91,7 +95,7 @@ public class APIPublisherUtil { } api.setResponseCache(APIConstants.DISABLED); - String endpointConfig = "{\"production_endpoints\":{\"url\":\" " + config.getEndpoint() + "\",\"config\":null},\"endpoint_type\":\"http\"}"; + String endpointConfig = "{\"production_endpoints\":{\"url\":\" " + config.getEndpoint() + "\",\"config\":null},\"implementation_status\":\"managed\",\"endpoint_type\":\"http\"}"; api.setEndpointConfig(endpointConfig); if ("".equals(id.getVersion()) || (DEFAULT_API_VERSION.equals(id.getVersion()))) { diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java index 10a20d9a48f..2a67c78713d 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java @@ -59,7 +59,6 @@ public class APIPublisherServiceComponent { if (log.isDebugEnabled()) { log.debug("Initializing device management core bundle"); } - /* Registering declarative service instances exposed by DeviceManagementServiceComponent */ this.registerServices(componentContext); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java index a611a321ea3..0b4a3cff914 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java @@ -25,6 +25,7 @@ import org.apache.catalina.core.StandardContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.apimgt.api.model.*; +import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.webapp.publisher.*; import org.wso2.carbon.apimgt.webapp.publisher.config.APIResource; import org.wso2.carbon.apimgt.webapp.publisher.config.APIResourceConfiguration; @@ -51,7 +52,6 @@ public class APIPublisherLifecycleListener implements LifecycleListener { private static final String PARAM_MANAGED_API_TRANSPORTS = "managed-api-transports"; private static final String PARAM_MANAGED_API_IS_SECURED = "managed-api-isSecured"; private static final String PARAM_MANAGED_API_APPLICATION = "managed-api-application"; - private static final String PARAM_MANAGED_API_CONTEXT_TEMPLATE = "managed-api-context-template"; private static final String PARAM_SHARED_WITH_ALL_TENANTS = "isSharedWithAllTenants"; private static final String PARAM_PROVIDER_TENANT_DOMAIN = "providerTenantDomain"; private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.class); @@ -69,7 +69,7 @@ public class APIPublisherLifecycleListener implements LifecycleListener { AnnotationUtil annotationUtil = new AnnotationUtil(context); Set annotatedAPIClasses = annotationUtil. scanStandardContext(org.wso2.carbon.apimgt.annotations.api.API.class.getName()); - List apiDefinitions = annotationUtil.extractAPIInfo(annotatedAPIClasses); + List apiDefinitions = annotationUtil.extractAPIInfo(servletContext, annotatedAPIClasses); for (APIResourceConfiguration apiDefinition : apiDefinitions) { APIConfig apiConfig = this.buildApiConfig(servletContext, apiDefinition); @@ -156,14 +156,13 @@ public class APIPublisherLifecycleListener implements LifecycleListener { apiConfig.setTags(tags); } - String contextTemplate = servletContext.getInitParameter(PARAM_MANAGED_API_CONTEXT_TEMPLATE); - if (contextTemplate == null || contextTemplate.isEmpty()) { - if (log.isDebugEnabled()) { - log.debug("'managed-api-context-template' attribute is not configured. Therefore, using the default," + - " " + - "which is the original context template assigned to the web application"); - } - contextTemplate = servletContext.getContextPath(); + String tenantDomain = servletContext.getInitParameter(PARAM_PROVIDER_TENANT_DOMAIN); + tenantDomain = (tenantDomain != null && !tenantDomain.isEmpty()) ? tenantDomain : + MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; + apiConfig.setTenantDomain(tenantDomain); + String contextTemplate = context + "/" + APIConstants.VERSION_PLACEHOLDER; + if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + contextTemplate = context + "/t/" + tenantDomain + "/" + APIConstants.VERSION_PLACEHOLDER; } apiConfig.setContextTemplate(contextTemplate); @@ -172,7 +171,8 @@ public class APIPublisherLifecycleListener implements LifecycleListener { if (log.isDebugEnabled()) { log.debug("'managed-api-endpoint' attribute is not configured"); } - endpoint = APIPublisherUtil.getApiEndpointUrl(context); + String endpointContext = servletContext.getContextPath(); + endpoint = APIPublisherUtil.getApiEndpointUrl(endpointContext); } apiConfig.setEndpoint(endpoint); @@ -208,13 +208,10 @@ public class APIPublisherLifecycleListener implements LifecycleListener { apiConfig.setTransports(transports); String sharingValueParam = servletContext.getInitParameter(PARAM_SHARED_WITH_ALL_TENANTS); - boolean isSharedWithAllTenants = (sharingValueParam == null || (!sharingValueParam.isEmpty()) && Boolean.parseBoolean(sharingValueParam) ); + boolean isSharedWithAllTenants = (sharingValueParam == null || (!sharingValueParam.isEmpty()) && Boolean.parseBoolean( + sharingValueParam)); apiConfig.setSharedWithAllTenants(isSharedWithAllTenants); - String tenantDomain = servletContext.getInitParameter(PARAM_PROVIDER_TENANT_DOMAIN); - tenantDomain = (tenantDomain!= null && !tenantDomain.isEmpty()) ? tenantDomain : MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; - apiConfig.setTenantDomain(tenantDomain); - Set uriTemplates = new LinkedHashSet(); for (APIResource apiResource : apidef.getResources()) { URITemplate template = new URITemplate(); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationUtil.java index 31372e70c35..a26c2042f1b 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationUtil.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationUtil.java @@ -92,7 +92,7 @@ public class AnnotationUtil { * @param entityClasses * @return */ - public List extractAPIInfo(Set entityClasses) + public List extractAPIInfo(final ServletContext servletContext, Set entityClasses) throws ClassNotFoundException { List apiResourceConfigs = new ArrayList(); @@ -111,7 +111,7 @@ public class AnnotationUtil { classLoader.loadClass(org.wso2.carbon.apimgt.annotations.api.API.class.getName()); Annotation apiAnno = clazz.getAnnotation(apiClazz); - List resourceList = null; + List resourceList; apiResourceConfig = new APIResourceConfiguration(); if (apiAnno != null) { @@ -139,21 +139,27 @@ public class AnnotationUtil { break; } } - - String rootContext = ""; + // All the apis should map to same root "/" + String rootContext = servletContext.getContextPath(); pathClazz = (Class) classLoader.loadClass(Path.class.getName()); pathClazzMethods = pathClazz.getMethods(); Annotation rootContectAnno = clazz.getAnnotation(pathClazz); + String subContext = ""; if (rootContectAnno != null) { - rootContext = invokeMethod(pathClazzMethods[0], rootContectAnno, STRING); + subContext = invokeMethod(pathClazzMethods[0], rootContectAnno, STRING); + if (subContext != null && !subContext.isEmpty()) { + rootContext = rootContext + "/" + subContext; + } else { + subContext = ""; + } if (log.isDebugEnabled()) { log.debug("API Root Context = " + rootContext); } } Method[] annotatedMethods = clazz.getDeclaredMethods(); - resourceList = getApiResources(rootContext, annotatedMethods); + resourceList = getApiResources(rootContext, subContext, annotatedMethods); apiResourceConfig.setResources(resourceList); } catch (Throwable throwable) { log.error("Error encountered while scanning for annotations", throwable); @@ -171,7 +177,7 @@ public class AnnotationUtil { return apiResourceConfigs; } - private List getApiResources(String rootContext, Method[] annotatedMethods) throws Throwable { + private List getApiResources(String resourceRootContext, String apiRootContext, Method[] annotatedMethods) throws Throwable { List resourceList; resourceList = new ArrayList(); for (Method method : annotatedMethods) { @@ -179,12 +185,13 @@ public class AnnotationUtil { if (methodContextAnno != null) { String subCtx = invokeMethod(pathClazzMethods[0], methodContextAnno, STRING); APIResource resource = new APIResource(); - resource.setUriTemplate(makeContextURLReady(subCtx)); + resource.setUriTemplate(makeContextURLReady(apiRootContext + subCtx)); String serverIP = System.getProperty(SERVER_HOST); String httpServerPort = System.getProperty(HTTP_PORT); - resource.setUri(PROTOCOL_HTTP + "://" + serverIP + ":" + httpServerPort + makeContextURLReady(rootContext) + makeContextURLReady(subCtx)); + resource.setUri(PROTOCOL_HTTP + "://" + serverIP + ":" + httpServerPort + makeContextURLReady( + resourceRootContext) + makeContextURLReady(subCtx)); resource.setAuthType(AUTH_TYPE); Annotation[] annotations = method.getDeclaredAnnotations(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/pom.xml index e0c6345ebb8..d5b807adb7b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/pom.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/pom.xml @@ -80,10 +80,6 @@ org.wso2.carbon.analytics-common org.wso2.carbon.databridge.commons - - org.wso2.carbon.analytics - org.wso2.carbon.analytics.api - org.wso2.carbon.registry org.wso2.carbon.registry.indexing @@ -123,7 +119,6 @@ org.wso2.carbon.context;version="${carbon.kernel.version.range}", org.wso2.carbon.utils;version="${carbon.kernel.version.range}", org.wso2.carbon.databridge.*;version="${carbon.analytics.common.version.range}", - org.wso2.carbon.analytics.*;version="${carbon.analytics.version.range}", org.wso2.carbon.registry.core.*;resolution:=optional, org.wso2.carbon.registry.common.*;version="${carbon.registry.imp.pkg.version.range}", org.wso2.carbon.registry.indexing.*; version="${carbon.registry.imp.pkg.version.range}", diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/AnalyticsDataRecord.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/AnalyticsDataRecord.java deleted file mode 100644 index ac1f50f13a5..00000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/AnalyticsDataRecord.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.device.mgt.analytics.data.publisher; - -import java.util.HashMap; -import java.util.Map; - -public class AnalyticsDataRecord { - private Map values; - private long timestamp; - - public AnalyticsDataRecord() { - values = new HashMap<>(); - } - - public AnalyticsDataRecord(Map values) { - this.values = values; - } - - public Map getValues() { - return this.values; - } - - public void setValue(String name, Object value) { - values.put(name, value); - } - - public Object getValue(String name) { - return this.values.get(name); - } - - public void setValues(Map values) { - this.values = values; - } - - public long getTimestamp() { - return this.timestamp; - } - - public void setTimestamp(long timestamp) { - this.timestamp = timestamp; - } -} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DeviceAnalyticsUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DataPublisherUtil.java similarity index 97% rename from components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DeviceAnalyticsUtil.java rename to components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DataPublisherUtil.java index c622369b18b..a13310ee942 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DeviceAnalyticsUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DataPublisherUtil.java @@ -25,7 +25,7 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; -public class DeviceAnalyticsUtil { +public class DataPublisherUtil { public static Document convertToDocument(File file) throws DataPublisherConfigurationException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DeviceDataPublisher.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DeviceDataPublisher.java index 2891904561e..bcf51ebdae8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DeviceDataPublisher.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/DeviceDataPublisher.java @@ -34,7 +34,7 @@ import org.wso2.carbon.databridge.commons.exception.TransportException; import org.wso2.carbon.device.mgt.analytics.data.publisher.config.AnalyticsConfiguration; import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherAlreadyExistsException; import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; -import org.wso2.carbon.device.mgt.analytics.data.publisher.internal.DeviceAnalyticsDataHolder; +import org.wso2.carbon.device.mgt.analytics.data.publisher.internal.DataPublisherDataHolder; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.exceptions.RegistryException; @@ -71,7 +71,7 @@ public class DeviceDataPublisher { return deviceDataPublisher; } - private DeviceDataPublisher() { + public DeviceDataPublisher() { dataPublisherMap = new ConcurrentHashMap<>(); } @@ -196,7 +196,7 @@ public class DeviceDataPublisher { try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true); - RegistryService registryService = DeviceAnalyticsDataHolder.getInstance().getRegistryService(); + RegistryService registryService = DataPublisherDataHolder.getInstance().getRegistryService(); if (registryService != null) { Registry registry = registryService.getConfigSystemRegistry(tenantId); this.loadTenantRegistry(tenantId); @@ -213,8 +213,8 @@ public class DeviceDataPublisher { } private void loadTenantRegistry(int tenantId) throws RegistryException { - TenantRegistryLoader tenantRegistryLoader = DeviceAnalyticsDataHolder.getInstance().getTenantRegistryLoader(); - DeviceAnalyticsDataHolder.getInstance().getIndexLoaderService().loadTenantIndex(tenantId); + TenantRegistryLoader tenantRegistryLoader = DataPublisherDataHolder.getInstance().getTenantRegistryLoader(); + DataPublisherDataHolder.getInstance().getIndexLoaderService().loadTenantIndex(tenantId); tenantRegistryLoader.loadTenantRegistry(tenantId); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/config/AnalyticsConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/config/AnalyticsConfiguration.java index c08dfc420ff..8c08d5eccf4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/config/AnalyticsConfiguration.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/config/AnalyticsConfiguration.java @@ -21,7 +21,7 @@ package org.wso2.carbon.device.mgt.analytics.data.publisher.config; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; -import org.wso2.carbon.device.mgt.analytics.data.publisher.DeviceAnalyticsUtil; +import org.wso2.carbon.device.mgt.analytics.data.publisher.DataPublisherUtil; import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; import org.wso2.carbon.utils.CarbonUtils; @@ -100,7 +100,7 @@ public class AnalyticsConfiguration { public static void init() throws DataPublisherConfigurationException { try { File authConfig = new File(AnalyticsConfiguration.DEVICE_ANALYTICS_CONFIG_PATH); - Document doc = DeviceAnalyticsUtil.convertToDocument(authConfig); + Document doc = DataPublisherUtil.convertToDocument(authConfig); /* Un-marshaling device analytics configuration */ JAXBContext ctx = JAXBContext.newInstance(AnalyticsConfiguration.class); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/exception/DeviceManagementAnalyticsException.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/exception/DeviceManagementAnalyticsException.java deleted file mode 100644 index 021ddc9b1e5..00000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/exception/DeviceManagementAnalyticsException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.device.mgt.analytics.data.publisher.exception; - -public class DeviceManagementAnalyticsException extends Exception { - public DeviceManagementAnalyticsException() { - super(); - } - - public DeviceManagementAnalyticsException(String message) { - super(message); - } - - public DeviceManagementAnalyticsException(String message, Throwable cause) { - super(message, cause); - } - - public DeviceManagementAnalyticsException(Throwable cause) { - super(cause); - } - - protected DeviceManagementAnalyticsException(String message, Throwable cause, - boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } -} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DeviceAnalyticsDataHolder.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DataPublisherDataHolder.java similarity index 74% rename from components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DeviceAnalyticsDataHolder.java rename to components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DataPublisherDataHolder.java index 9de111fb9c2..6f132b3fb82 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DeviceAnalyticsDataHolder.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DataPublisherDataHolder.java @@ -18,36 +18,24 @@ */ package org.wso2.carbon.device.mgt.analytics.data.publisher.internal; -import org.wso2.carbon.analytics.api.AnalyticsDataAPI; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; -public class DeviceAnalyticsDataHolder { - private static DeviceAnalyticsDataHolder thisInstance = new DeviceAnalyticsDataHolder(); - /** - * AnalyticsDataAPI is service used to retrieve data from DAS. - */ - private AnalyticsDataAPI analyticsDataAPI; +public class DataPublisherDataHolder { + private static DataPublisherDataHolder thisInstance = new DataPublisherDataHolder(); + private TenantRegistryLoader tenantRegistryLoader; private TenantIndexingLoader indexLoader; private RegistryService registryService; - private DeviceAnalyticsDataHolder() { + private DataPublisherDataHolder() { } - public static DeviceAnalyticsDataHolder getInstance() { + public static DataPublisherDataHolder getInstance() { return thisInstance; } - public AnalyticsDataAPI getAnalyticsDataAPI() { - return analyticsDataAPI; - } - - public void setAnalyticsDataAPI(AnalyticsDataAPI analyticsDataAPI) { - this.analyticsDataAPI = analyticsDataAPI; - } - public void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader){ this.tenantRegistryLoader = tenantRegistryLoader; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DeviceAnalyticsServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DataPublisherServiceComponent.java similarity index 67% rename from components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DeviceAnalyticsServiceComponent.java rename to components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DataPublisherServiceComponent.java index 83f71348ac8..2314b738061 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DeviceAnalyticsServiceComponent.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/internal/DataPublisherServiceComponent.java @@ -23,23 +23,16 @@ import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentContext; -import org.wso2.carbon.analytics.api.AnalyticsDataAPI; import org.wso2.carbon.device.mgt.analytics.data.publisher.config.AnalyticsConfiguration; -import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService; -import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsServiceImpl; +import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; +import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherServiceImpl; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; /** - * @scr.component name="org.wso2.carbon.device.mgt.analytics.internal.DeviceAnalyticsServiceComponent" + * @scr.component name="org.wso2.carbon.device.mgt.analytics.data.publisher.internal.DataPublisherServiceComponent" * immediate="true" - * @scr.reference name="device.analytics.api" - * interface="org.wso2.carbon.analytics.api.AnalyticsDataAPI" - * cardinality="1..1" - * policy="dynamic" - * bind="setAnalyticsDataAPI" - * unbind="unsetAnalyticsDataAPI" * @scr.reference name="registry.service" * interface="org.wso2.carbon.registry.core.service.RegistryService" * cardinality="1..1" @@ -58,10 +51,10 @@ import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; * bind="setIndexLoader" * unbind="unsetIndexLoader" */ -public class DeviceAnalyticsServiceComponent { +public class DataPublisherServiceComponent { private ServiceRegistration analyticsServiceRef; - private static Log log = LogFactory.getLog(DeviceAnalyticsServiceComponent.class); + private static Log log = LogFactory.getLog(DataPublisherServiceComponent.class); protected void activate(ComponentContext componentCtx) { try { @@ -72,7 +65,7 @@ public class DeviceAnalyticsServiceComponent { BundleContext bundleCtx = componentCtx.getBundleContext(); this.analyticsServiceRef = - bundleCtx.registerService(DeviceAnalyticsService.class, new DeviceAnalyticsServiceImpl(), null); + bundleCtx.registerService(EventsPublisherService.class, new EventsPublisherServiceImpl(), null); if (log.isDebugEnabled()) { log.debug("Device management analytics bundle has been successfully initialized"); @@ -94,58 +87,34 @@ public class DeviceAnalyticsServiceComponent { } } - /** - * Sets AnalyticsDataAPI Service. - * - * @param analyticsDataAPI An instance of AnalyticsDataAPI - */ - protected void setAnalyticsDataAPI(AnalyticsDataAPI analyticsDataAPI) { - if (log.isDebugEnabled()) { - log.debug("Setting AnalyticsDataAPI Service"); - } - DeviceAnalyticsDataHolder.getInstance().setAnalyticsDataAPI(analyticsDataAPI); - } - - /** - * Un sets AnalyticsDataAPI Service. - * - * @param analyticsDataAPI An instance of AnalyticsDataAPI - */ - protected void unsetAnalyticsDataAPI(AnalyticsDataAPI analyticsDataAPI) { - if (log.isDebugEnabled()) { - log.debug("Un-Setting AnalyticsDataAPI Service"); - } - DeviceAnalyticsDataHolder.getInstance().setAnalyticsDataAPI(null); - } - protected void setRegistryService(RegistryService registryService) { if (registryService != null && log.isDebugEnabled()) { log.debug("Registry service initialized"); } - DeviceAnalyticsDataHolder.getInstance().setRegistryService(registryService); + DataPublisherDataHolder.getInstance().setRegistryService(registryService); } protected void unsetRegistryService(RegistryService registryService) { - DeviceAnalyticsDataHolder.getInstance().setRegistryService(null); + DataPublisherDataHolder.getInstance().setRegistryService(null); } protected void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { - DeviceAnalyticsDataHolder.getInstance().setTenantRegistryLoader(tenantRegistryLoader); + DataPublisherDataHolder.getInstance().setTenantRegistryLoader(tenantRegistryLoader); } protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { - DeviceAnalyticsDataHolder.getInstance().setTenantRegistryLoader(null); + DataPublisherDataHolder.getInstance().setTenantRegistryLoader(null); } protected void setIndexLoader(TenantIndexingLoader indexLoader) { if (indexLoader != null && log.isDebugEnabled()) { log.debug("IndexLoader service initialized"); } - DeviceAnalyticsDataHolder.getInstance().setIndexLoaderService(indexLoader); + DataPublisherDataHolder.getInstance().setIndexLoaderService(indexLoader); } protected void unsetIndexLoader(TenantIndexingLoader indexLoader) { - DeviceAnalyticsDataHolder.getInstance().setIndexLoaderService(null); + DataPublisherDataHolder.getInstance().setIndexLoaderService(null); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/DeviceAnalyticsServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/DeviceAnalyticsServiceImpl.java deleted file mode 100644 index c0f2ab6ad52..00000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/DeviceAnalyticsServiceImpl.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.device.mgt.analytics.data.publisher.service; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.analytics.api.AnalyticsDataAPI; -import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse; -import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDrillDownRequest; -import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry; -import org.wso2.carbon.analytics.dataservice.core.AnalyticsDataServiceUtils; -import org.wso2.carbon.analytics.datasource.commons.Record; -import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException; -import org.wso2.carbon.context.CarbonContext; -import org.wso2.carbon.databridge.agent.DataPublisher; -import org.wso2.carbon.databridge.commons.utils.DataBridgeCommonsUtils; -import org.wso2.carbon.device.mgt.analytics.data.publisher.AnalyticsDataRecord; -import org.wso2.carbon.device.mgt.analytics.data.publisher.DeviceDataPublisher; -import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; -import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DeviceManagementAnalyticsException; -import org.wso2.carbon.device.mgt.analytics.data.publisher.internal.DeviceAnalyticsDataHolder; - -import java.util.ArrayList; -import java.util.List; - -/** - * This is the implementation of Osgi Service which can be used to publish and retireved - * event/records. - */ -public class DeviceAnalyticsServiceImpl implements DeviceAnalyticsService { - private static Log log = LogFactory.getLog(DeviceAnalyticsServiceImpl.class); - - /** - * @param streamName is the name of the stream that the data needs to pushed - * @param version is the version of the stream - * @param metaDataArray - meta data that needs to pushed - * @param correlationDataArray - correlation data that needs to be pushed - * @param payloadDataArray - payload data that needs to be pushed - * @return - * @throws DataPublisherConfigurationException - */ - @Override - public boolean publishEvent(String streamName, String version, Object[] metaDataArray, - Object[] correlationDataArray, - Object[] payloadDataArray) throws DataPublisherConfigurationException { - DataPublisher dataPublisher = DeviceDataPublisher.getInstance().getDataPublisher(); - if (dataPublisher != null) { - String streamId = DataBridgeCommonsUtils.generateStreamId(streamName, version); - return dataPublisher.tryPublish(streamId, System.currentTimeMillis(), metaDataArray, correlationDataArray, - payloadDataArray); - } else { - return false; - } - } - - /** - * @param tableName is the name of the table that events need to be retrieved - * @param query is query to be executed. - * @return - * @throws AnalyticsException - */ - @Override - public List getAllEventsForDevice(String tableName, String query) throws - DeviceManagementAnalyticsException { - try { - int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); - AnalyticsDataAPI analyticsDataAPI = DeviceAnalyticsDataHolder.getInstance().getAnalyticsDataAPI(); - int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query); - if (eventCount == 0) { - return new ArrayList<>(); - } - AnalyticsDrillDownRequest drillDownRequest = new AnalyticsDrillDownRequest(); - drillDownRequest.setQuery(query); - drillDownRequest.setTableName(tableName); - drillDownRequest.setRecordCount(eventCount); - List resultEntries = analyticsDataAPI.drillDownSearch(tenantId, drillDownRequest); - List recordIds = getRecordIds(resultEntries); - AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds); - List records = AnalyticsDataServiceUtils.listRecords(analyticsDataAPI, response); - return getAnalyticsDataRecords(records); - } catch (AnalyticsException e) { - throw new DeviceManagementAnalyticsException( - "Failed fetch data for table " + tableName + "with the query " + query); - } - } - - private List getRecordIds(List searchResults) { - List ids = new ArrayList<>(); - for (SearchResultEntry searchResult : searchResults) { - ids.add(searchResult.getId()); - } - return ids; - } - - private List getAnalyticsDataRecords(List records) { - List analyticsDataRecords = new ArrayList<>(); - for (Record record : records) { - AnalyticsDataRecord analyticsDataRecord = new AnalyticsDataRecord(record.getValues()); - analyticsDataRecords.add(analyticsDataRecord); - } - return analyticsDataRecords; - } - -} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/DeviceAnalyticsService.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherService.java similarity index 69% rename from components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/DeviceAnalyticsService.java rename to components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherService.java index 4b918d03850..7be1ac574b8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/DeviceAnalyticsService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherService.java @@ -18,16 +18,12 @@ */ package org.wso2.carbon.device.mgt.analytics.data.publisher.service; -import org.wso2.carbon.device.mgt.analytics.data.publisher.AnalyticsDataRecord; import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; -import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DeviceManagementAnalyticsException; - -import java.util.List; /** * This service can be used to publish and retreive data from the Analytics Server. */ -public interface DeviceAnalyticsService { +public interface EventsPublisherService { /** * This is used to publish an event to DAS. @@ -42,14 +38,4 @@ public interface DeviceAnalyticsService { boolean publishEvent(String streamName, String version, Object[] metaDataArray, Object[] correlationDataArray, Object[] payloadDataArray) throws DataPublisherConfigurationException; - /** - * This service can be used to retrieve all the event for the query. - * @param tableName is the name of the table that events need to be retrieved - * @param query is query to be executed. - * @return the record list - * @throws DeviceManagementAnalyticsException - */ - List getAllEventsForDevice(String tableName, - String query) throws DeviceManagementAnalyticsException; - } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherServiceImpl.java new file mode 100644 index 00000000000..63e5bee1a60 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.analytics.data.publisher/src/main/java/org/wso2/carbon/device/mgt/analytics/data/publisher/service/EventsPublisherServiceImpl.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.device.mgt.analytics.data.publisher.service; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.databridge.agent.DataPublisher; +import org.wso2.carbon.databridge.commons.utils.DataBridgeCommonsUtils; +import org.wso2.carbon.device.mgt.analytics.data.publisher.DeviceDataPublisher; +import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; + +/** + * This is the implementation of Osgi Service which can be used to publish and retireved + * event/records. + */ +public class EventsPublisherServiceImpl implements EventsPublisherService { + private static Log log = LogFactory.getLog(EventsPublisherServiceImpl.class); + + /** + * @param streamName is the name of the stream that the data needs to pushed + * @param version is the version of the stream + * @param metaDataArray - meta data that needs to pushed + * @param correlationDataArray - correlation data that needs to be pushed + * @param payloadDataArray - payload data that needs to be pushed + * @return + * @throws DataPublisherConfigurationException + */ + @Override + public boolean publishEvent(String streamName, String version, Object[] metaDataArray, + Object[] correlationDataArray, + Object[] payloadDataArray) throws DataPublisherConfigurationException { + DataPublisher dataPublisher = DeviceDataPublisher.getInstance().getDataPublisher(); + if (dataPublisher != null) { + String streamId = DataBridgeCommonsUtils.generateStreamId(streamName, version); + return dataPublisher.tryPublish(streamId, System.currentTimeMillis(), metaDataArray, correlationDataArray, + payloadDataArray); + } else { + return false; + } + } + + + +} \ No newline at end of file diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/pom.xml b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/pom.xml index 0f86757cea3..5592ee46a39 100644 --- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/pom.xml +++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/pom.xml @@ -90,10 +90,6 @@ commons-lang.wso2 commons-lang - - org.wso2.carbon.analytics - org.wso2.carbon.analytics.api - org.wso2.carbon.registry org.wso2.carbon.registry.indexing diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClient.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClient.java index fc50292de54..8251a1bceed 100644 --- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClient.java +++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClient.java @@ -18,13 +18,6 @@ package org.wso2.carbon.identity.jwt.client.extension; -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.JWSSigner; -import com.nimbusds.jose.crypto.RSASSASigner; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,32 +29,21 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.message.BasicNameValuePair; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; -import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.core.util.KeyStoreManager; +import org.json.simple.parser.ParseException;; import org.wso2.carbon.identity.jwt.client.extension.constant.JWTConstants; import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.identity.jwt.client.extension.dto.JWTConfig; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; import org.wso2.carbon.identity.jwt.client.extension.util.JWTClientUtil; -import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.net.MalformedURLException; -import java.net.URI; import java.net.URL; import java.security.KeyManagementException; -import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.security.interfaces.RSAPrivateKey; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import java.util.Random; /** * this class represents an implementation of Token Client which is based on JWT @@ -69,12 +51,6 @@ import java.util.Random; public class JWTClient { private static Log log = LogFactory.getLog(JWTClient.class); - private static final String JWT_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"; - private static final String GRANT_TYPE_PARAM_NAME = "grant_type"; - private static final String REFRESH_TOKEN_GRANT_TYPE = "refresh_token"; - private static final String REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME = "refresh_token"; - private static final String JWT_PARAM_NAME = "assertion"; - private static final String SCOPE_PARAM_NAME = "scope"; private JWTConfig jwtConfig; public JWTClient(JWTConfig jwtConfig) { @@ -87,13 +63,13 @@ public class JWTClient { public AccessTokenInfo getAccessToken(String consumerKey, String consumerSecret, String username, String scopes) throws JWTClientException { List params = new ArrayList<>(); - params.add(new BasicNameValuePair(GRANT_TYPE_PARAM_NAME, JWT_GRANT_TYPE)); - String assertion = generateSignedJWTAssertion(username); + params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, JWTConstants.JWT_GRANT_TYPE)); + String assertion = JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig); if (assertion == null) { throw new JWTClientException("JWT is not configured properly for user : " + username); } - params.add(new BasicNameValuePair(JWT_PARAM_NAME, assertion)); - params.add(new BasicNameValuePair(SCOPE_PARAM_NAME, scopes)); + params.add(new BasicNameValuePair(JWTConstants.JWT_PARAM_NAME, assertion)); + params.add(new BasicNameValuePair(JWTConstants.SCOPE_PARAM_NAME, scopes)); return getTokenInfo(params, consumerKey, consumerSecret); } @@ -104,9 +80,9 @@ public class JWTClient { String consumerKey, String consumerSecret) throws JWTClientException { List params = new ArrayList<>(); - params.add(new BasicNameValuePair(GRANT_TYPE_PARAM_NAME, REFRESH_TOKEN_GRANT_TYPE)); - params.add(new BasicNameValuePair(REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME, refreshToken)); - params.add(new BasicNameValuePair(SCOPE_PARAM_NAME, scopes)); + params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, JWTConstants.REFRESH_TOKEN_GRANT_TYPE)); + params.add(new BasicNameValuePair(JWTConstants.REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME, refreshToken)); + params.add(new BasicNameValuePair(JWTConstants.SCOPE_PARAM_NAME, scopes)); return getTokenInfo(params, consumerKey, consumerSecret); } @@ -132,10 +108,10 @@ public class JWTClient { JSONParser jsonParser = new JSONParser(); JSONObject jsonObject = (JSONObject) jsonParser.parse(response); AccessTokenInfo accessTokenInfo = new AccessTokenInfo(); - accessTokenInfo.setAccess_token((String) jsonObject.get(JWTConstants.OAUTH_ACCESS_TOKEN)); - accessTokenInfo.setRefresh_token((String) jsonObject.get(JWTConstants.OAUTH_REFRESH_TOKEN)); - accessTokenInfo.setExpires_in((Long) jsonObject.get(JWTConstants.OAUTH_EXPIRES_IN)); - accessTokenInfo.setToken_type((String) jsonObject.get(JWTConstants.OAUTH_TOKEN_TYPE)); + accessTokenInfo.setAccessToken((String) jsonObject.get(JWTConstants.ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME)); + accessTokenInfo.setRefreshToken((String) jsonObject.get(JWTConstants.REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME)); + accessTokenInfo.setExpiresIn((Long) jsonObject.get(JWTConstants.OAUTH_EXPIRES_IN)); + accessTokenInfo.setTokenType((String) jsonObject.get(JWTConstants.OAUTH_TOKEN_TYPE)); return accessTokenInfo; } catch (MalformedURLException e) { throw new JWTClientException("Invalid URL for token endpoint " + jwtConfig.getTokenEndpoint(), e); @@ -156,92 +132,7 @@ public class JWTClient { return new String(Base64.encodeBase64((consumerKey + ":" + consumerSecret).getBytes())); } - public String generateSignedJWTAssertion(String username) throws JWTClientException { - try { - String subject = username; - long currentTimeMillis = System.currentTimeMillis(); - // add the skew between servers - String iss = jwtConfig.getIssuer(); - if (iss == null || iss.isEmpty()) { - return null; - } - currentTimeMillis += jwtConfig.getSkew(); - long iat = currentTimeMillis + jwtConfig.getIssuedInternal() * 60 * 1000; - long exp = currentTimeMillis + jwtConfig.getExpirationTime() * 60 * 1000; - long nbf = currentTimeMillis + jwtConfig.getValidityPeriodFromCurrentTime() * 60 * 1000; - String jti = jwtConfig.getJti(); - if (jti == null) { - String defaultTokenId = currentTimeMillis + "" + new Random().nextInt(); - jti = defaultTokenId; - } - List aud = jwtConfig.getAudiences(); - //set up the basic claims - JWTClaimsSet claimsSet = new JWTClaimsSet(); - claimsSet.setIssueTime(new Date(iat)); - claimsSet.setExpirationTime(new Date(exp)); - claimsSet.setIssuer(iss); - claimsSet.setSubject(username); - claimsSet.setNotBeforeTime(new Date(nbf)); - claimsSet.setJWTID(jti); - claimsSet.setAudience(aud); - - // get Keystore params - String keyStorePath = jwtConfig.getKeyStorePath(); - String privateKeyAlias = jwtConfig.getPrivateKeyAlias(); - String privateKeyPassword = jwtConfig.getPrivateKeyPassword(); - KeyStore keyStore; - RSAPrivateKey rsaPrivateKey; - if (keyStorePath != null && !keyStorePath.isEmpty()) { - String keyStorePassword = jwtConfig.getKeyStorePassword(); - keyStore = loadKeyStore(new File(keyStorePath), keyStorePassword, "JKS"); - rsaPrivateKey = (RSAPrivateKey) keyStore.getKey(privateKeyAlias, privateKeyPassword.toCharArray()); - } else { - int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); - KeyStoreManager tenantKeyStoreManager = KeyStoreManager.getInstance(tenantId); - rsaPrivateKey = (RSAPrivateKey) tenantKeyStoreManager.getDefaultPrivateKey(); - } - JWSSigner signer = new RSASSASigner(rsaPrivateKey); - SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet); - signedJWT.sign(signer); - String assertion = signedJWT.serialize(); - return assertion; - } catch (KeyStoreException e) { - throw new JWTClientException("Failed loading the keystore.", e); - } catch (IOException e) { - throw new JWTClientException("Failed parsing the keystore file.", e); - } catch (NoSuchAlgorithmException e) { - throw new JWTClientException("No such algorithm found RS256.", e); - } catch (CertificateException e) { - throw new JWTClientException("Failed loading the certificate from the keystore.", e); - } catch (UnrecoverableKeyException e) { - throw new JWTClientException("Failed loading the keys from the keystore.", e); - } catch (JOSEException e) { - throw new JWTClientException(e); - } catch (Exception e) { - //This is thrown when loading default private key. - throw new JWTClientException("Failed loading the private key.", e); - } - } - private KeyStore loadKeyStore(final File keystoreFile, final String password, final String keyStoreType) - throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { - if (null == keystoreFile) { - throw new IllegalArgumentException("Keystore url may not be null"); - } - URI keystoreUri = keystoreFile.toURI(); - URL keystoreUrl = keystoreUri.toURL(); - KeyStore keystore = KeyStore.getInstance(keyStoreType); - InputStream is = null; - try { - is = keystoreUrl.openStream(); - keystore.load(is, null == password ? null : password.toCharArray()); - } finally { - if (null != is) { - is.close(); - } - } - return keystore; - } } diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/constant/JWTConstants.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/constant/JWTConstants.java index 106c5228009..ab6a4b142d1 100644 --- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/constant/JWTConstants.java +++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/constant/JWTConstants.java @@ -21,8 +21,15 @@ package org.wso2.carbon.identity.jwt.client.extension.constant; * This holds the constants related JWT client component. */ public class JWTConstants { - public static final String OAUTH_ACCESS_TOKEN = "access_token"; - public static final String OAUTH_REFRESH_TOKEN = "refresh_token"; public static final String OAUTH_EXPIRES_IN = "expires_in"; public static final String OAUTH_TOKEN_TYPE = "token_type"; + public static final String JWT_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"; + public static final String GRANT_TYPE_PARAM_NAME = "grant_type"; + public static final String REFRESH_TOKEN_GRANT_TYPE = "refresh_token"; + public static final String REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME = "refresh_token"; + public static final String ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME = "access_token"; + public static final String JWT_PARAM_NAME = "assertion"; + public static final String SCOPE_PARAM_NAME = "scope"; + public static final String DEFAULT_JWT_CLIENT = "default-jwt-client"; } + diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/dto/AccessTokenInfo.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/dto/AccessTokenInfo.java index 146ddf128a1..c1adb813fd4 100644 --- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/dto/AccessTokenInfo.java +++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/dto/AccessTokenInfo.java @@ -23,40 +23,40 @@ package org.wso2.carbon.identity.jwt.client.extension.dto; */ public class AccessTokenInfo { - private String token_type; - private long expires_in; - private String refresh_token; - private String access_token; + private String tokenType; + private long expiresIn; + private String refreshToken; + private String accessToken; - public String getToken_type() { - return token_type; + public String getTokenType() { + return tokenType; } - public void setToken_type(String token_type) { - this.token_type = token_type; + public void setTokenType(String tokenType) { + this.tokenType = tokenType; } - public long getExpires_in() { - return expires_in; + public long getExpiresIn() { + return expiresIn; } - public void setExpires_in(long expres_in) { - this.expires_in = expres_in; + public void setExpiresIn(long expiresIn) { + this.expiresIn = expiresIn; } - public String getRefresh_token() { - return refresh_token; + public String getRefreshToken() { + return refreshToken; } - public void setRefresh_token(String refresh_token) { - this.refresh_token = refresh_token; + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; } - public String getAccess_token() { - return access_token; + public String getAccessToken() { + return accessToken; } - public void setAccess_token(String access_token) { - this.access_token = access_token; + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; } } diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/internal/JWTClientExtensionServiceComponent.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/internal/JWTClientExtensionServiceComponent.java index ff59df5fd32..3ca17170896 100644 --- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/internal/JWTClientExtensionServiceComponent.java +++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/internal/JWTClientExtensionServiceComponent.java @@ -20,7 +20,11 @@ package org.wso2.carbon.identity.jwt.client.extension.internal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientConfigurationException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerServiceImpl; import org.wso2.carbon.identity.jwt.client.extension.util.JWTClientUtil; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.service.RegistryService; @@ -66,11 +70,16 @@ public class JWTClientExtensionServiceComponent { log.debug("Initializing jwt extension bundle"); } try { - JWTClientUtil.initialize(); + JWTClientManagerService jwtClientManagerService = new JWTClientManagerServiceImpl(); + JWTClientUtil.initialize(jwtClientManagerService); + BundleContext bundleContext = componentContext.getBundleContext(); + bundleContext.registerService(JWTClientManagerService.class.getName(), jwtClientManagerService, null); } catch (RegistryException e) { log.error("Failed loading the jwt config from registry.", e); } catch (IOException e) { log.error("Failed loading the jwt config from the file system.", e); + } catch (JWTClientConfigurationException e) { + log.error("Failed to set default jwt configurations.", e); } } diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/service/JWTClientManagerService.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/service/JWTClientManagerService.java new file mode 100644 index 00000000000..83e4ca8884f --- /dev/null +++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/service/JWTClientManagerService.java @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* 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 org.wso2.carbon.identity.jwt.client.extension.service; + +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientConfigurationException; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; + +import java.util.Properties; + +/** + * This is the JWTClientManagerServiceImpl Service that can be used to have JWT Client for tenant specific. + */ +public interface JWTClientManagerService { + + /** + * This return the jwt based token client to generate token for the tenant. + * @return JWTClient that can be used to generate token. + * @throws JWTClientException when the JWT Client creation fails + */ + JWTClient getJWTClient() throws JWTClientException; + + /** + * This will set the default JWT Client that will be used if there is any available for tenants. + * @param properties required to configure jwt client. + * @throws JWTClientConfigurationException throws when the configuration is invalid. + */ + void setDefaultJWTClient(Properties properties) throws JWTClientConfigurationException; +} diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClientManager.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/service/JWTClientManagerServiceImpl.java similarity index 62% rename from components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClientManager.java rename to components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/service/JWTClientManagerServiceImpl.java index bea6664a108..eee439d7685 100644 --- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClientManager.java +++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/service/JWTClientManagerServiceImpl.java @@ -16,12 +16,15 @@ * under the License. */ -package org.wso2.carbon.identity.jwt.client.extension; +package org.wso2.carbon.identity.jwt.client.extension.service; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.constant.JWTConstants; import org.wso2.carbon.identity.jwt.client.extension.dto.JWTConfig; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientAlreadyExistsException; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientConfigurationException; @@ -36,42 +39,44 @@ import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; /** - * This creates JWT Client for each tenant. + * This creates JWT Client for each tenant and implements the JWTClientManagerService interface. */ -public class JWTClientManager { +public class JWTClientManagerServiceImpl implements JWTClientManagerService{ private static Map jwtClientMap; - private static JWTClientManager jwtClientCreator; - private static final Log log = LogFactory.getLog(JWTClientManager.class); + private static final Log log = LogFactory.getLog(JWTClientManagerServiceImpl.class); private static final String TENANT_JWT_CONFIG_LOCATION = "/jwt-config/jwt.properties"; + private static JWTClient defaultJWTClient; - public static JWTClientManager getInstance() { - if (jwtClientCreator == null) { - synchronized (JWTClientManager.class) { - if (jwtClientCreator == null) { - jwtClientCreator = new JWTClientManager(); - } - } - } - return jwtClientCreator; - } - private JWTClientManager() { + public JWTClientManagerServiceImpl() { jwtClientMap = new ConcurrentHashMap<>(); } /** * this return the jwt based token client to generate token for the tenant. */ + @Override public JWTClient getJWTClient() throws JWTClientException { String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + if (tenantId == -1) { + throw new JWTClientException("Invalid tenant domain :" + tenantDomain); + } //Get jwt client which has been registered for the tenant. JWTClient jwtClient = getJWTClient(tenantDomain); if (jwtClient == null) { - //Create new jwt client for the tenant. + //Create a new jwt client for the tenant. try { - JWTConfig jwtConfig = new JWTConfig(getJWTConfig(tenantId)); + Properties properties = getJWTConfigProperties(tenantId); + if (properties == null) { + if (defaultJWTClient != null) { + return defaultJWTClient; + } else { + throw new JWTClientException("JWT Configuration is not available for tenant " + tenantDomain); + } + } + JWTConfig jwtConfig = new JWTConfig(properties); jwtClient = new JWTClient(jwtConfig); addJWTClient(tenantDomain, jwtClient); } catch (JWTClientAlreadyExistsException e) { @@ -85,6 +90,31 @@ public class JWTClientManager { return jwtClient; } + /** + * This will set the default JWT Client that will be used if there is any available for tenants. + */ + @Override + public void setDefaultJWTClient(Properties properties) throws JWTClientConfigurationException { + if (properties == null) { + throw new JWTClientConfigurationException("Failed to load jwt configuration for super tenant."); + } + String defaultJWTClientMode = properties.getProperty(JWTConstants.DEFAULT_JWT_CLIENT); + boolean isDefaultJwtClient = false; + if (defaultJWTClientMode != null && !defaultJWTClientMode.isEmpty()) { + isDefaultJwtClient = Boolean.parseBoolean(defaultJWTClientMode); + } + if (isDefaultJwtClient) { + try { + JWTConfig jwtConfig = new JWTConfig(properties); + defaultJWTClient = new JWTClient(jwtConfig); + addJWTClient(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, defaultJWTClient); + } catch (JWTClientAlreadyExistsException e) { + log.warn("Attempting to register a jwt client for the super tenant" + + " when one already exists. Returning existing jwt client"); + } + } + } + /** * Fetch the jwt client which has been registered under the tenant domain. * @@ -106,23 +136,25 @@ public class JWTClientManager { * @throws JWTClientAlreadyExistsException - If a jwt client has already been registered under the tenantdomain */ private void addJWTClient(String tenantDomain, JWTClient jwtClient) throws JWTClientAlreadyExistsException { - if (jwtClientMap.containsKey(tenantDomain)) { - throw new JWTClientAlreadyExistsException("A jwt client has already been created for the tenant " + tenantDomain); + synchronized (jwtClientMap) { + if (jwtClientMap.containsKey(tenantDomain)) { + throw new JWTClientAlreadyExistsException( + "A jwt client has already been created for the tenant " + tenantDomain); + } + jwtClientMap.put(tenantDomain, jwtClient); } - jwtClientMap.put(tenantDomain, jwtClient); } /** * Retrieve JWT configs from registry. */ - private Properties getJWTConfig(int tenantId) throws JWTClientConfigurationException { + private Properties getJWTConfigProperties(int tenantId) throws JWTClientConfigurationException { try { Resource config = JWTClientUtil.getConfigRegistryResourceContent(tenantId, TENANT_JWT_CONFIG_LOCATION); - Properties properties = new Properties(); - if(config != null) { + Properties properties = null; + if (config != null) { + properties = new Properties(); properties.load(config.getContentStream()); - } else { - throw new JWTClientConfigurationException("Failed to load jwt configuration for tenant id : " + tenantId); } return properties; } catch (RegistryException e) { diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/util/JWTClientUtil.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/util/JWTClientUtil.java index 9cb0792487e..352e8177aa7 100644 --- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/util/JWTClientUtil.java +++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/util/JWTClientUtil.java @@ -17,7 +17,13 @@ */ package org.wso2.carbon.identity.jwt.client.extension.util; -import org.apache.commons.io.FileUtils; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.crypto.RSASSASigner; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; @@ -27,8 +33,12 @@ import org.apache.http.conn.ssl.SSLContextBuilder; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; -import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.util.KeyStoreManager; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; +import org.wso2.carbon.identity.jwt.client.extension.dto.JWTConfig; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientConfigurationException; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; import org.wso2.carbon.identity.jwt.client.extension.internal.JWTClientExtensionDataHolder; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.Resource; @@ -36,13 +46,25 @@ import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.utils.CarbonUtils; + import java.io.BufferedReader; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; +import java.net.URI; +import java.net.URL; import java.security.KeyManagementException; +import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.interfaces.RSAPrivateKey; +import java.util.Date; +import java.util.List; +import java.util.Properties; +import java.util.Random; /** * This is the utility class that is used for JWT Client. @@ -55,8 +77,10 @@ public class JWTClientUtil { private static final String JWT_CONFIG_FILE_NAME = "jwt.properties"; private static final String SUPERTENANT_JWT_CONFIG_LOCATION = CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + JWT_CONFIG_FILE_NAME; + /** * Return a http client instance + * * @param protocol- service endpoint protocol http/https * @return */ @@ -96,12 +120,14 @@ public class JWTClientUtil { } } - public static void initialize() throws RegistryException, IOException { - Resource resource = getConfigRegistryResourceContent(MultitenantConstants.SUPER_TENANT_ID, TENANT_JWT_CONFIG_LOCATION); - if (resource == null) { - File configFile = new File(SUPERTENANT_JWT_CONFIG_LOCATION); - String contents = FileUtils.readFileToString(configFile, "UTF-8"); - addJWTConfigResourceToRegistry(MultitenantConstants.SUPER_TENANT_ID, contents); + public static void initialize(JWTClientManagerService jwtClientManagerService) + throws RegistryException, IOException, JWTClientConfigurationException { + File configFile = new File(SUPERTENANT_JWT_CONFIG_LOCATION); + if (configFile.exists()) { + InputStream propertyStream = configFile.toURI().toURL().openStream(); + Properties properties = new Properties(); + properties.load(propertyStream); + jwtClientManagerService.setDefaultJWTClient(properties); } } @@ -136,7 +162,7 @@ public class JWTClientUtil { /** * Get the jwt details from the registry for tenants. * - * @param tenantId for accesing tenant space. + * @param tenantId for accesing tenant space. * @return the config for tenant * @throws RegistryException */ @@ -161,8 +187,96 @@ public class JWTClientUtil { } private static void loadTenantRegistry(int tenantId) throws RegistryException { - TenantRegistryLoader tenantRegistryLoader = JWTClientExtensionDataHolder.getInstance().getTenantRegistryLoader(); + TenantRegistryLoader tenantRegistryLoader = + JWTClientExtensionDataHolder.getInstance().getTenantRegistryLoader(); JWTClientExtensionDataHolder.getInstance().getIndexLoaderService().loadTenantIndex(tenantId); tenantRegistryLoader.loadTenantRegistry(tenantId); } + + public static String generateSignedJWTAssertion(String username, JWTConfig jwtConfig) throws JWTClientException { + try { + String subject = username; + long currentTimeMillis = System.currentTimeMillis(); + // add the skew between servers + String iss = jwtConfig.getIssuer(); + if (iss == null || iss.isEmpty()) { + return null; + } + currentTimeMillis += jwtConfig.getSkew(); + long iat = currentTimeMillis + jwtConfig.getIssuedInternal() * 60 * 1000; + long exp = currentTimeMillis + jwtConfig.getExpirationTime() * 60 * 1000; + long nbf = currentTimeMillis + jwtConfig.getValidityPeriodFromCurrentTime() * 60 * 1000; + String jti = jwtConfig.getJti(); + if (jti == null) { + String defaultTokenId = currentTimeMillis + "" + new Random().nextInt(); + jti = defaultTokenId; + } + List aud = jwtConfig.getAudiences(); + //set up the basic claims + JWTClaimsSet claimsSet = new JWTClaimsSet(); + claimsSet.setIssueTime(new Date(iat)); + claimsSet.setExpirationTime(new Date(exp)); + claimsSet.setIssuer(iss); + claimsSet.setSubject(username); + claimsSet.setNotBeforeTime(new Date(nbf)); + claimsSet.setJWTID(jti); + claimsSet.setAudience(aud); + + // get Keystore params + String keyStorePath = jwtConfig.getKeyStorePath(); + String privateKeyAlias = jwtConfig.getPrivateKeyAlias(); + String privateKeyPassword = jwtConfig.getPrivateKeyPassword(); + KeyStore keyStore; + RSAPrivateKey rsaPrivateKey; + if (keyStorePath != null && !keyStorePath.isEmpty()) { + String keyStorePassword = jwtConfig.getKeyStorePassword(); + keyStore = loadKeyStore(new File(keyStorePath), keyStorePassword, "JKS"); + rsaPrivateKey = (RSAPrivateKey) keyStore.getKey(privateKeyAlias, privateKeyPassword.toCharArray()); + } else { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + KeyStoreManager tenantKeyStoreManager = KeyStoreManager.getInstance(tenantId); + rsaPrivateKey = (RSAPrivateKey) tenantKeyStoreManager.getDefaultPrivateKey(); + } + JWSSigner signer = new RSASSASigner(rsaPrivateKey); + SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet); + signedJWT.sign(signer); + String assertion = signedJWT.serialize(); + return assertion; + } catch (KeyStoreException e) { + throw new JWTClientException("Failed loading the keystore.", e); + } catch (IOException e) { + throw new JWTClientException("Failed parsing the keystore file.", e); + } catch (NoSuchAlgorithmException e) { + throw new JWTClientException("No such algorithm found RS256.", e); + } catch (CertificateException e) { + throw new JWTClientException("Failed loading the certificate from the keystore.", e); + } catch (UnrecoverableKeyException e) { + throw new JWTClientException("Failed loading the keys from the keystore.", e); + } catch (JOSEException e) { + throw new JWTClientException(e); + } catch (Exception e) { + //This is thrown when loading default private key. + throw new JWTClientException("Failed loading the private key.", e); + } + } + + private static KeyStore loadKeyStore(final File keystoreFile, final String password, final String keyStoreType) + throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { + if (null == keystoreFile) { + throw new IllegalArgumentException("Keystore url may not be null"); + } + URI keystoreUri = keystoreFile.toURI(); + URL keystoreUrl = keystoreUri.toURL(); + KeyStore keystore = KeyStore.getInstance(keyStoreType); + InputStream is = null; + try { + is = keystoreUrl.openStream(); + keystore.load(is, null == password ? null : password.toCharArray()); + } finally { + if (null != is) { + is.close(); + } + } + return keystore; + } } diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationValve.java b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationValve.java index f7211fef132..93ab9c32a3b 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationValve.java +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/src/main/java/org/wso2/carbon/webapp/authenticator/framework/WebappAuthenticationValve.java @@ -45,8 +45,6 @@ public class WebappAuthenticationValve extends CarbonTomcatValve { return; } - - WebappAuthenticator authenticator = WebappAuthenticatorFactory.getAuthenticator(request); if (authenticator == null) { String msg = "Failed to load an appropriate authenticator to authenticate the request"; diff --git a/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/CDMF_DEFAULT_IDP.xml b/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/CDMF_DEFAULT_IDP.xml deleted file mode 100644 index 2741e45be00..00000000000 --- a/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/CDMF_DEFAULT_IDP.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - CDMF_DEFAULT_IDP - CDMF_DEFAULT_IDP - - https://localhost:9443/oauth2/token - true - - - - - - - - - - - - - MIIFkzCCA3sCBAKkVfcwDQYJKoZIhvcNAQEFBQAwgY0xCzAJBgNVBAYTAlNMMRAwDgYDVQQIEwdXZXN0ZXJuMRAwDgYDVQQHEwdDb2xvbWJvMQ0wCwYDVQQKEwRXU08yMRQwEgYDVQQLEwtFbmdpbmVlcmluZzESMBAGA1UEAxMJbG9jYWxob3N0MSEwHwYJKoZIhvcNAQkBFhJpb3RzZXJ2ZXJAd3NvMi5jb20wHhcNMTUxMjE3MTMxMTA0WhcNMTcxMjE2MTMxMTA0WjCBjTELMAkGA1UEBhMCU0wxEDAOBgNVBAgTB1dlc3Rlcm4xEDAOBgNVBAcTB0NvbG9tYm8xDTALBgNVBAoTBFdTTzIxFDASBgNVBAsTC0VuZ2luZWVyaW5nMRIwEAYDVQQDEwlsb2NhbGhvc3QxITAfBgkqhkiG9w0BCQEWEmlvdHNlcnZlckB3c28yLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALkiGVQ9tZOKIi/gD/toV+enq+neqOBGYQ8Fq/ABOWnK2QpGWm81+Rets5GbQ6W//D8C5TOBGqK7z+LAgdmILr1XLkvrXWoan0GPdDJ1wpc2/6XDZvM5f7Y8cmRqVPJv7AF+ImgF9dqv97gYCiujy+nNHd5Nk/60pco2LBV5SyLqqrzKXEnSGrS4zoYWpPeJ9YrXPEkW7A6AxTQK0yU9Ej4TktgafbTueythrLomKiZJj4wPxm2lA2lAZscDdws9NWrI5z/LUVLbUMxrY10Nig1liX5b1mrUk5bb1d2tqwkPrpRILKoOBJtI674SQS3GziiUiCJGIO/EGGRn1AJsC/SvnnEez3WKY/DgJ6102MWK/yWtY8NYHUX2anwMBS7UpT5A4BXdsfBz3R+iPF99FxdAGGsS4GQuuPocZaycLqoPCxpTSSxBsKMUcKpn3yaiQRd6uDuiTNt7odDOQj0Tno7uokh/HILgbzvj9EExDOsdwLVvqYmUHBPeLmiICWXfi4kyH/twPOZtV9eVnfWYx5Kwg+2Y4fIb3q4ABr0hzxaMYHQo6NOukSH1BcdAWiQIXbSFFaTZD8p6OfiZpHcQ59HT/Z8GBlCFL2xkYJFmOhXI/Cu+xrcwqEIInv7d8w3eiNQ7MneomEptLbBk9+kMsP0ubo34oOGHR9qk3Lj580c/AgMBAAEwDQYJKoZIhvcNAQEFBQADggIBADw70g2/wrgzrAM8OXBlthGbCEaXZpKwq9IJN0qu+/l+PNwF7csQhj+qW+zMrWaH1DGWJroaei1+NFFrj/pvp61rF/ZeTPGVJd7puCq++SevqIrzKyAEBtwtpXmcFhBpV/FrQAv3ODOJ3bN2wSRPZHUvARTBB3RaUI06g1jCaBzjDEGoMfSxdr5/Ty2WxTI9u9RlIs3Q52AiOmROtLPiEQZQIqfNO3cxCEWojHxPqVEZA/kQYy+rryj4H0zzSrj7QFlQhsMDw5j8bv9AcvTEGmwp29avsgnceDWinI6lwtd8zqh0ZW9QJdH0BRNCM/EkTlTUHeEg04/sOgOrlWcvEfVxDqNEtbUzU9UFxl0lkQkuRn1UdxZlvhWaFnel5iRC9b7OZvi2mkVujLyxEWlJB1tuyMLQxu6PfabBVODP5V8/+uyiiK/gwrB5rYl8RHxGoznJnI1Y3HVzKlA849CrMBaY5vnhE03cNja7QroPzLmmuXBLk2LbI1lu5nJAqKpBUPMI/IU3pF4Q7VTD2ZANI+ktGgGlM8AK4OJHWOhj8W289pWTHVjG8syPLTsaYkhgLjzZl/g9cUwn/96NJNvzd3dkT+7VgE+BJOLofq25CjZcN1M7MhWdl3vbWNj9vzL0+FCnwca8UecfvFS39PIekIvqbtP+Gw8NiYOUGIllZ0JH - - - - \ No newline at end of file diff --git a/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/jwt.properties b/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/jwt.properties index 503301fb80b..d6a1f0fc2be 100644 --- a/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/jwt.properties +++ b/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/jwt.properties @@ -41,7 +41,7 @@ skew=0 #jti=token123 #KeyStore to cryptographic credentials -#KeyStore=src/main/resources/wso2carbon.jks +#KeyStore=repository/resources/security/wso2carbon.jks #Password of the KeyStore #KeyStorePassword=wso2carbon @@ -52,3 +52,6 @@ skew=0 #Private key password to retrieve the private key used to sign #AuthnRequest and LogoutRequest messages #PrivateKeyPassword=wso2carbon + +#this will be used as the default IDP config if there isn't any config available for tenants. +default-jwt-client=true diff --git a/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/p2.inf b/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/p2.inf index 9e8c8bd070b..5678ff874ef 100644 --- a/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/p2.inf +++ b/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/p2.inf @@ -1,3 +1,2 @@ instructions.configure = \ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.jwt.client.extension_${feature.version}/jwt.properties,target:${installFolder}/../../conf/etc/jwt.properties,overwrite:true);\ -org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.jwt.client.extension_${feature.version}/CDMF_DEFAULT_IDP.xml,target:${installFolder}/../../conf/identity/identity-providers/CDMF_DEFAULT_IDP.xml,overwrite:true);\ diff --git a/pom.xml b/pom.xml index b0bab3e94b5..8e16d112ac0 100644 --- a/pom.xml +++ b/pom.xml @@ -1391,13 +1391,6 @@ ${carbon.analytics.common.version} - - - org.wso2.carbon.analytics - org.wso2.carbon.analytics.api - ${carbon.analytics.version} - - org.wso2.carbon.registry @@ -1750,10 +1743,6 @@ 5.0.11 [5.0.11,6.0.0) - - 1.0.5 - [1.0.5,2.0.0] - 4.4.8 [4.4.8, 5.0.0)