Merge pull request #212 from ayyoob/das-ext

few changes in web app publishing after enabling synapse gateway and added jwt and app registration code changes
merge-requests/7/head
Prabath Abeysekara 9 years ago
commit d6a6a5e689

@ -77,7 +77,18 @@
<artifactId>commons-httpclient</artifactId> <artifactId>commons-httpclient</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.base</artifactId>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple.wso2</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.user.api</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.wso2.carbon</groupId> <groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId> <artifactId>org.wso2.carbon.utils</artifactId>

@ -53,6 +53,11 @@ public interface ApiApplicationRegistrationService {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
Response register(RegistrationProfile registrationProfile); 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 @DELETE
Response unregister(@QueryParam("applicationName") String applicationName); Response unregister(@QueryParam("applicationName") String applicationName);
} }

@ -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.constants.ApiApplicationConstants;
import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; 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.context.PrivilegedCarbonContext;
import org.wso2.carbon.apimgt.application.extension.api.util.APIUtil; import org.wso2.carbon.apimgt.application.extension.api.util.APIUtil;
import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreException;
@ -45,13 +46,16 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
@POST @POST
public Response register(@PathParam("tenantDomain") String tenantDomain, public Response register(@PathParam("tenantDomain") String tenantDomain,
@QueryParam("applicationName") String applicationName) { @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 { try {
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
if (PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId() == -1) { if (PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId() == -1) {
String msg = "Invalid tenant domain : " + tenantDomain; 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() String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
.getRealmConfiguration().getAdminUserName(); .getRealmConfiguration().getAdminUserName();
@ -63,21 +67,19 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
} catch (APIManagerException e) { } catch (APIManagerException e) {
String msg = "Error occurred while registering an application '" + applicationName + "'"; String msg = "Error occurred while registering an application '" + applicationName + "'";
log.error(msg, e); 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) { } catch (UserStoreException e) {
String msg = "Failed to retrieve the tenant" + tenantDomain + "'"; String msg = "Failed to retrieve the tenant" + tenantDomain + "'";
log.error(msg, e); 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 { } finally {
PrivilegedCarbonContext.endTenantFlow(); PrivilegedCarbonContext.endTenantFlow();
} }
return response;
} }
@Path("register") @Path("register")
@POST @POST
public Response register(RegistrationProfile registrationProfile) { public Response register(RegistrationProfile registrationProfile) {
Response response;
try { try {
String username = APIUtil.getAuthenticatedUser(); String username = APIUtil.getAuthenticatedUser();
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
@ -93,8 +95,9 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD); ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD);
apiManagementProviderService.registerExistingOAuthApplicationToAPIApplication( apiManagementProviderService.registerExistingOAuthApplicationToAPIApplication(
jsonStringObject.toJSONString(), registrationProfile.getApplicationName(), jsonStringObject.toJSONString(), registrationProfile.getApplicationName(),
registrationProfile.getConsumerKey(), username, registrationProfile.isAllowedToAllDomains()); registrationProfile.getConsumerKey(), username, registrationProfile.isAllowedToAllDomains(),
return Response.status(Response.Status.ACCEPTED).entity("OAuth App is mapped as APIM App").build(); ApiApplicationConstants.DEFAULT_TOKEN_TYPE);
return Response.status(Response.Status.ACCEPTED).entity("true").build();
} else { } else {
ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
registrationProfile.getApplicationName(), registrationProfile.getTags(), registrationProfile.getApplicationName(), registrationProfile.getTags(),
@ -103,17 +106,15 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
} }
} catch (APIManagerException e) { } catch (APIManagerException e) {
String msg = "Error occurred while registering an application '" String msg = "Error occurred while registering an application '"
+ registrationProfile.getApplicationName() + "'"; + registrationProfile.getApplicationName() + "'";
log.error(msg, e); 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") @Path("unregister")
@DELETE @DELETE
public Response unregister(@QueryParam("applicationName") String applicationName) { public Response unregister(@QueryParam("applicationName") String applicationName) {
Response response;
try { try {
String username = APIUtil.getAuthenticatedUser(); String username = APIUtil.getAuthenticatedUser();
APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService(); APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
@ -122,8 +123,7 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi
} catch (APIManagerException e) { } catch (APIManagerException e) {
String msg = "Error occurred while removing the application '" + applicationName; String msg = "Error occurred while removing the application '" + applicationName;
log.error(msg, e); 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;
} }
} }

@ -30,7 +30,7 @@
<!-- Device related APIs --> <!-- Device related APIs -->
<Permission> <Permission>
<name>Register tenant specific application</name> <name>Register tenant specific application</name>
<path>/permission/super admin</path> <path>/device-mgt</path>
<url>/register/tenants/*</url> <url>/register/tenants/*</url>
<method>POST</method> <method>POST</method>
<scope>super_admin_user</scope> <scope>super_admin_user</scope>

@ -59,7 +59,7 @@ public interface APIManagementProviderService {
* Register existing Oauth application as apim application. * Register existing Oauth application as apim application.
*/ */
void registerExistingOAuthApplicationToAPIApplication(String jsonString, String applicationName, String clientId, void registerExistingOAuthApplicationToAPIApplication(String jsonString, String applicationName, String clientId,
String username, boolean isAllowedAllDomains) String username, boolean isAllowedAllDomains, String keyType)
throws APIManagerException; throws APIManagerException;
/** /**

@ -118,13 +118,47 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
@Override @Override
public void registerExistingOAuthApplicationToAPIApplication(String jsonString, String applicationName, public void registerExistingOAuthApplicationToAPIApplication(String jsonString, String applicationName,
String clientId, String username, String clientId, String username,
boolean isAllowedAllDomains) boolean isAllowedAllDomains, String keyType)
throws APIManagerException { throws APIManagerException {
try { try {
APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username); APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
if (apiConsumer != null) { if (apiConsumer != null) {
String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain()); 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]; String[] allowedDomains = new String[1];
if (isAllowedAllDomains) { if (isAllowedAllDomains) {
allowedDomains[0] = ApiApplicationConstants.ALLOWED_DOMAINS; allowedDomains[0] = ApiApplicationConstants.ALLOWED_DOMAINS;
@ -286,14 +320,18 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
try { try {
APIConsumer consumer = APIManagerFactory.getInstance().getAPIConsumer(subscriberName); APIConsumer consumer = APIManagerFactory.getInstance().getAPIConsumer(subscriberName);
if (consumer != null) { if (consumer != null) {
Subscriber subscriber = new Subscriber(subscriberName); synchronized (consumer) {
subscriber.setSubscribedDate(new Date()); if (consumer.getSubscriber(subscriberName) == null) {
subscriber.setEmail(subscriberEmail); Subscriber subscriber = new Subscriber(subscriberName);
subscriber.setTenantId(tenantId); subscriber.setSubscribedDate(new Date());
consumer.addSubscriber(subscriber, groupId); subscriber.setEmail(subscriberEmail);
if (log.isDebugEnabled()) { subscriber.setTenantId(tenantId);
log.debug("Successfully created subscriber with name : " + subscriberName + " with groupID : " + consumer.addSubscriber(subscriber, groupId);
groupId); if (log.isDebugEnabled()) {
log.debug("Successfully created subscriber with name : " + subscriberName +
" with groupID : " + groupId);
}
}
} }
} else { } else {
throw new APIManagerException("API provider configured for the given API configuration is null. " + 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) { if (userVisibleAPIs != null) {
Set<SubscribedAPI> subscribedAPIs = apiConsumer.getSubscribedAPIs(subscriber, apiApplicationName, Set<SubscribedAPI> subscribedAPIs = apiConsumer.getSubscribedAPIs(subscriber, apiApplicationName,
groupId); groupId);
for (API userVisbleAPI : userVisibleAPIs) { for (API userVisibleAPI : userVisibleAPIs) {
APIIdentifier apiIdentifier = userVisbleAPI.getId(); APIIdentifier apiIdentifier = userVisibleAPI.getId();
boolean isSubscribed = false; boolean isSubscribed = false;
if (subscribedAPIs != null) { if (subscribedAPIs != null) {
for (SubscribedAPI subscribedAPI : subscribedAPIs) { for (SubscribedAPI subscribedAPI : subscribedAPIs) {

@ -26,18 +26,22 @@ import org.wso2.carbon.apimgt.api.APIProvider;
import org.wso2.carbon.apimgt.api.FaultGatewaysException; import org.wso2.carbon.apimgt.api.FaultGatewaysException;
import org.wso2.carbon.apimgt.api.model.API; import org.wso2.carbon.apimgt.api.model.API;
import org.wso2.carbon.apimgt.api.model.APIIdentifier; 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.api.model.URITemplate;
import org.wso2.carbon.apimgt.impl.APIManagerFactory; import org.wso2.carbon.apimgt.impl.APIManagerFactory;
import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder; 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.governance.lcm.util.CommonUtil;
import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* This class represents the concrete implementation of the APIPublisherService that corresponds to providing all * 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 { public class APIPublisherServiceImpl implements APIPublisherService {
private static final Log log = LogFactory.getLog(APIPublisherServiceImpl.class); private static final Log log = LogFactory.getLog(APIPublisherServiceImpl.class);
private static final String PUBLISH_ACTION = "Publish";
@Override @Override
public void publishAPI(API api) throws APIManagementException, FaultGatewaysException { public void publishAPI(final API api) throws APIManagementException, FaultGatewaysException {
if (log.isDebugEnabled()) { String tenantDomain = MultitenantUtils.getTenantDomain(api.getApiOwner());
log.debug("Publishing API '" + api.getId() + "'"); PrivilegedCarbonContext.startTenantFlow();
} PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
try { try {
String tenantDomain = MultitenantUtils.getTenantDomain(api.getApiOwner()); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
int tenantId = // Below code snippet is added to load API Lifecycle in tenant mode.
APIPublisherDataHolder.getInstance().getRealmService().getTenantManager().getTenantId(tenantDomain); RegistryService registryService = APIPublisherDataHolder.getInstance().getRegistryService();
// Below code snippet is added load API Lifecycle in tenant mode, where in it does not load when tenant is loaded. CommonUtil.addDefaultLifecyclesIfNotAvailable(registryService.getConfigSystemRegistry(tenantId),
RegistryService registryService = APIPublisherDataHolder.getInstance().getRegistryService(); CommonUtil.getRootSystemRegistry(tenantId));
CommonUtil.addDefaultLifecyclesIfNotAvailable(registryService.getConfigSystemRegistry(tenantId), APIProvider provider = APIManagerFactory.getInstance().getAPIProvider(api.getApiOwner());
CommonUtil.getRootSystemRegistry(tenantId)); MultitenantUtils.getTenantDomain(api.getApiOwner());
APIProvider provider = APIManagerFactory.getInstance().getAPIProvider(api.getApiOwner()); if (provider != null) {
MultitenantUtils.getTenantDomain(api.getApiOwner()); if (provider.isDuplicateContextTemplate(api.getContext())) {
if (provider != null) { throw new APIManagementException(
if (!provider.isAPIAvailable(api.getId())) { "Error occurred while adding the API. A duplicate API" +
provider.addAPI(api); " context already exists for " + api.getContext());
log.info("Successfully published API '" + api.getId().getApiName() + "' with context '" + }
api.getContext() + "' and version '" + api.getId().getVersion() + "'"); if (!provider.isAPIAvailable(api.getId())) {
} else { provider.addAPI(api);
provider.updateAPI(api); provider.changeLifeCycleStatus(api.getId(), PUBLISH_ACTION);
log.info("An API already exists with the name '" + api.getId().getApiName() + "', context '" + if (log.isDebugEnabled()) {
api.getContext() + "' and version '" + api.getId().getVersion() + log.debug("Successfully published API '" + api.getId().getApiName() +
"'. Thus, the API config is updated"); "' with context '" + api.getContext() + "' and version '"
} + api.getId().getVersion() + "'");
provider.saveSwagger20Definition(api.getId(), createSwaggerDefinition(api)); }
} else { } else {
throw new APIManagementException("API provider configured for the given API configuration is null. " + api.setStatus(APIStatus.PUBLISHED);
"Thus, the API is not published"); provider.updateAPI(api);
} if (log.isDebugEnabled()) {
} catch (UserStoreException e) { log.debug("An API already exists with the name '" + api.getId().getApiName() +
throw new APIManagementException("Failed to get the tenant id for the user " + api.getApiOwner(), e); "', context '" + api.getContext() + "' and version '"
} catch (FileNotFoundException e) { + api.getId().getVersion() + "'. Thus, the API config is updated");
throw new APIManagementException("Failed to retrieve life cycle file ", e); }
} catch (RegistryException e) { }
throw new APIManagementException("Failed to access the registry ", e); provider.saveSwagger20Definition(api.getId(), createSwaggerDefinition(api));
} catch (XMLStreamException e) { } else {
throw new APIManagementException("Failed parsing the lifecycle xml.", e); throw new APIManagementException("API provider configured for the given API configuration " +
} "is null. Thus, the API is not published");
} }
} catch (FileNotFoundException e) {
private String createSwaggerDefinition(API api) { throw new APIManagementException("Failed to retrieve life cycle file ", e);
//{"paths":{"/controller/*":{"get":{"responses":{"200":{}}}},"/manager/*":{"get":{"responses":{"200":{}}}}}, } catch (RegistryException e) {
// "swagger":"2.0","info":{"title":"RaspberryPi","version":"1.0.0"}} throw new APIManagementException("Failed to access the registry ", e);
JsonObject swaggerDefinition = new JsonObject(); } catch (XMLStreamException e) {
throw new APIManagementException("Failed parsing the lifecycle xml.", e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
JsonObject paths = new JsonObject(); private String createSwaggerDefinition(API api) {
for (URITemplate uriTemplate : api.getUriTemplates()) { Map<String, JsonObject> httpVerbsMap = new HashMap<>();
JsonObject response = new JsonObject();
response.addProperty("200", "");
JsonObject responses = new JsonObject(); for (URITemplate uriTemplate : api.getUriTemplates()) {
responses.add("responses", response); JsonObject response = new JsonObject();
response.addProperty("200", "");
JsonObject httpVerb = new JsonObject(); JsonObject responses = new JsonObject();
httpVerb.add(uriTemplate.getHTTPVerb().toLowerCase(), responses); 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(); Iterator it = httpVerbsMap.entrySet().iterator();
path.add(uriTemplate.getUriTemplate(), httpVerb); JsonObject paths = new JsonObject();
while (it.hasNext()) {
Map.Entry<String, JsonObject> pair = (Map.Entry) it.next();
paths.add(pair.getKey(), pair.getValue());
it.remove();
}
paths.add(uriTemplate.getUriTemplate(), httpVerb); JsonObject info = new JsonObject();
} info.addProperty("title", api.getId().getApiName());
swaggerDefinition.add("paths", paths); info.addProperty("version", api.getId().getVersion());
swaggerDefinition.addProperty("swagger", "2.0");
JsonObject info = new JsonObject(); JsonObject swaggerDefinition = new JsonObject();
info.addProperty("title", api.getId().getApiName()); swaggerDefinition.add("paths", paths);
info.addProperty("version", api.getId().getVersion()); swaggerDefinition.addProperty("swagger", "2.0");
swaggerDefinition.add("info", info); swaggerDefinition.add("info", info);
return swaggerDefinition.toString(); return swaggerDefinition.toString();
//return "{\"paths\":{\"/controller/*\":{\"get\":{\"responses\":{\"200\":{}}}}, }
// \"/manager/*\":{\"get\":{\"responses\":{\"200\":{}}}}},\"swagger\":\"2.0\",
// \"info\":{\"title\":\"RaspberryPi\",\"version\":\"1.0.0\"}}";
}
@Override @Override
public void removeAPI(APIIdentifier id) throws APIManagementException { public void removeAPI(APIIdentifier id) throws APIManagementException {

@ -37,6 +37,7 @@ public class APIPublisherUtil {
private static final String DEFAULT_API_VERSION = "1.0.0"; private static final String DEFAULT_API_VERSION = "1.0.0";
public static final String API_VERSION_PARAM="{version}"; public static final String API_VERSION_PARAM="{version}";
public static final String API_PUBLISH_ENVIRONEMENT = "Production and Sandbox";
enum HTTPMethod { enum HTTPMethod {
GET, POST, DELETE, PUT, OPTIONS GET, POST, DELETE, PUT, OPTIONS
@ -75,10 +76,13 @@ public class APIPublisherUtil {
api.setUrl(config.getEndpoint()); api.setUrl(config.getEndpoint());
api.addAvailableTiers(provider.getTiers()); api.addAvailableTiers(provider.getTiers());
api.setEndpointSecured(true); api.setEndpointSecured(true);
api.setStatus(APIStatus.PUBLISHED); api.setStatus(APIStatus.CREATED);
api.setTransports(config.getTransports()); api.setTransports(config.getTransports());
api.setContextTemplate(config.getContextTemplate()); api.setContextTemplate(config.getContextTemplate());
api.setUriTemplates(config.getUriTemplates()); api.setUriTemplates(config.getUriTemplates());
Set<String> environements = new HashSet<>();
environements.add(API_PUBLISH_ENVIRONEMENT);
api.setEnvironments(environements);
Set<Tier> tiers = new HashSet<Tier>(); Set<Tier> tiers = new HashSet<Tier>();
tiers.add(new Tier(APIConstants.UNLIMITED_TIER)); tiers.add(new Tier(APIConstants.UNLIMITED_TIER));
api.addAvailableTiers(tiers); api.addAvailableTiers(tiers);
@ -91,7 +95,7 @@ public class APIPublisherUtil {
} }
api.setResponseCache(APIConstants.DISABLED); 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); api.setEndpointConfig(endpointConfig);
if ("".equals(id.getVersion()) || (DEFAULT_API_VERSION.equals(id.getVersion()))) { if ("".equals(id.getVersion()) || (DEFAULT_API_VERSION.equals(id.getVersion()))) {

@ -59,7 +59,6 @@ public class APIPublisherServiceComponent {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Initializing device management core bundle"); log.debug("Initializing device management core bundle");
} }
/* Registering declarative service instances exposed by DeviceManagementServiceComponent */ /* Registering declarative service instances exposed by DeviceManagementServiceComponent */
this.registerServices(componentContext); this.registerServices(componentContext);

@ -25,6 +25,7 @@ import org.apache.catalina.core.StandardContext;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.model.*; 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.*;
import org.wso2.carbon.apimgt.webapp.publisher.config.APIResource; import org.wso2.carbon.apimgt.webapp.publisher.config.APIResource;
import org.wso2.carbon.apimgt.webapp.publisher.config.APIResourceConfiguration; 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_TRANSPORTS = "managed-api-transports";
private static final String PARAM_MANAGED_API_IS_SECURED = "managed-api-isSecured"; 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_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_SHARED_WITH_ALL_TENANTS = "isSharedWithAllTenants";
private static final String PARAM_PROVIDER_TENANT_DOMAIN = "providerTenantDomain"; private static final String PARAM_PROVIDER_TENANT_DOMAIN = "providerTenantDomain";
private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.class); private static final Log log = LogFactory.getLog(APIPublisherLifecycleListener.class);
@ -69,7 +69,7 @@ public class APIPublisherLifecycleListener implements LifecycleListener {
AnnotationUtil annotationUtil = new AnnotationUtil(context); AnnotationUtil annotationUtil = new AnnotationUtil(context);
Set<String> annotatedAPIClasses = annotationUtil. Set<String> annotatedAPIClasses = annotationUtil.
scanStandardContext(org.wso2.carbon.apimgt.annotations.api.API.class.getName()); scanStandardContext(org.wso2.carbon.apimgt.annotations.api.API.class.getName());
List<APIResourceConfiguration> apiDefinitions = annotationUtil.extractAPIInfo(annotatedAPIClasses); List<APIResourceConfiguration> apiDefinitions = annotationUtil.extractAPIInfo(servletContext, annotatedAPIClasses);
for (APIResourceConfiguration apiDefinition : apiDefinitions) { for (APIResourceConfiguration apiDefinition : apiDefinitions) {
APIConfig apiConfig = this.buildApiConfig(servletContext, apiDefinition); APIConfig apiConfig = this.buildApiConfig(servletContext, apiDefinition);
@ -156,14 +156,13 @@ public class APIPublisherLifecycleListener implements LifecycleListener {
apiConfig.setTags(tags); apiConfig.setTags(tags);
} }
String contextTemplate = servletContext.getInitParameter(PARAM_MANAGED_API_CONTEXT_TEMPLATE); String tenantDomain = servletContext.getInitParameter(PARAM_PROVIDER_TENANT_DOMAIN);
if (contextTemplate == null || contextTemplate.isEmpty()) { tenantDomain = (tenantDomain != null && !tenantDomain.isEmpty()) ? tenantDomain :
if (log.isDebugEnabled()) { MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
log.debug("'managed-api-context-template' attribute is not configured. Therefore, using the default," + apiConfig.setTenantDomain(tenantDomain);
" " + String contextTemplate = context + "/" + APIConstants.VERSION_PLACEHOLDER;
"which is the original context template assigned to the web application"); if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
} contextTemplate = context + "/t/" + tenantDomain + "/" + APIConstants.VERSION_PLACEHOLDER;
contextTemplate = servletContext.getContextPath();
} }
apiConfig.setContextTemplate(contextTemplate); apiConfig.setContextTemplate(contextTemplate);
@ -172,7 +171,8 @@ public class APIPublisherLifecycleListener implements LifecycleListener {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("'managed-api-endpoint' attribute is not configured"); log.debug("'managed-api-endpoint' attribute is not configured");
} }
endpoint = APIPublisherUtil.getApiEndpointUrl(context); String endpointContext = servletContext.getContextPath();
endpoint = APIPublisherUtil.getApiEndpointUrl(endpointContext);
} }
apiConfig.setEndpoint(endpoint); apiConfig.setEndpoint(endpoint);
@ -208,13 +208,10 @@ public class APIPublisherLifecycleListener implements LifecycleListener {
apiConfig.setTransports(transports); apiConfig.setTransports(transports);
String sharingValueParam = servletContext.getInitParameter(PARAM_SHARED_WITH_ALL_TENANTS); 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); 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<URITemplate> uriTemplates = new LinkedHashSet<URITemplate>(); Set<URITemplate> uriTemplates = new LinkedHashSet<URITemplate>();
for (APIResource apiResource : apidef.getResources()) { for (APIResource apiResource : apidef.getResources()) {
URITemplate template = new URITemplate(); URITemplate template = new URITemplate();

@ -92,7 +92,7 @@ public class AnnotationUtil {
* @param entityClasses * @param entityClasses
* @return * @return
*/ */
public List<APIResourceConfiguration> extractAPIInfo(Set<String> entityClasses) public List<APIResourceConfiguration> extractAPIInfo(final ServletContext servletContext, Set<String> entityClasses)
throws ClassNotFoundException { throws ClassNotFoundException {
List<APIResourceConfiguration> apiResourceConfigs = new ArrayList<APIResourceConfiguration>(); List<APIResourceConfiguration> apiResourceConfigs = new ArrayList<APIResourceConfiguration>();
@ -111,7 +111,7 @@ public class AnnotationUtil {
classLoader.loadClass(org.wso2.carbon.apimgt.annotations.api.API.class.getName()); classLoader.loadClass(org.wso2.carbon.apimgt.annotations.api.API.class.getName());
Annotation apiAnno = clazz.getAnnotation(apiClazz); Annotation apiAnno = clazz.getAnnotation(apiClazz);
List<APIResource> resourceList = null; List<APIResource> resourceList;
apiResourceConfig = new APIResourceConfiguration(); apiResourceConfig = new APIResourceConfiguration();
if (apiAnno != null) { if (apiAnno != null) {
@ -139,21 +139,27 @@ public class AnnotationUtil {
break; break;
} }
} }
// All the apis should map to same root "/"
String rootContext = ""; String rootContext = servletContext.getContextPath();
pathClazz = (Class<Path>) classLoader.loadClass(Path.class.getName()); pathClazz = (Class<Path>) classLoader.loadClass(Path.class.getName());
pathClazzMethods = pathClazz.getMethods(); pathClazzMethods = pathClazz.getMethods();
Annotation rootContectAnno = clazz.getAnnotation(pathClazz); Annotation rootContectAnno = clazz.getAnnotation(pathClazz);
String subContext = "";
if (rootContectAnno != null) { 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()) { if (log.isDebugEnabled()) {
log.debug("API Root Context = " + rootContext); log.debug("API Root Context = " + rootContext);
} }
} }
Method[] annotatedMethods = clazz.getDeclaredMethods(); Method[] annotatedMethods = clazz.getDeclaredMethods();
resourceList = getApiResources(rootContext, annotatedMethods); resourceList = getApiResources(rootContext, subContext, annotatedMethods);
apiResourceConfig.setResources(resourceList); apiResourceConfig.setResources(resourceList);
} catch (Throwable throwable) { } catch (Throwable throwable) {
log.error("Error encountered while scanning for annotations", throwable); log.error("Error encountered while scanning for annotations", throwable);
@ -171,7 +177,7 @@ public class AnnotationUtil {
return apiResourceConfigs; return apiResourceConfigs;
} }
private List<APIResource> getApiResources(String rootContext, Method[] annotatedMethods) throws Throwable { private List<APIResource> getApiResources(String resourceRootContext, String apiRootContext, Method[] annotatedMethods) throws Throwable {
List<APIResource> resourceList; List<APIResource> resourceList;
resourceList = new ArrayList<APIResource>(); resourceList = new ArrayList<APIResource>();
for (Method method : annotatedMethods) { for (Method method : annotatedMethods) {
@ -179,12 +185,13 @@ public class AnnotationUtil {
if (methodContextAnno != null) { if (methodContextAnno != null) {
String subCtx = invokeMethod(pathClazzMethods[0], methodContextAnno, STRING); String subCtx = invokeMethod(pathClazzMethods[0], methodContextAnno, STRING);
APIResource resource = new APIResource(); APIResource resource = new APIResource();
resource.setUriTemplate(makeContextURLReady(subCtx)); resource.setUriTemplate(makeContextURLReady(apiRootContext + subCtx));
String serverIP = System.getProperty(SERVER_HOST); String serverIP = System.getProperty(SERVER_HOST);
String httpServerPort = System.getProperty(HTTP_PORT); 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); resource.setAuthType(AUTH_TYPE);
Annotation[] annotations = method.getDeclaredAnnotations(); Annotation[] annotations = method.getDeclaredAnnotations();

@ -80,10 +80,6 @@
<groupId>org.wso2.carbon.analytics-common</groupId> <groupId>org.wso2.carbon.analytics-common</groupId>
<artifactId>org.wso2.carbon.databridge.commons</artifactId> <artifactId>org.wso2.carbon.databridge.commons</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.api</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.wso2.carbon.registry</groupId> <groupId>org.wso2.carbon.registry</groupId>
<artifactId>org.wso2.carbon.registry.indexing</artifactId> <artifactId>org.wso2.carbon.registry.indexing</artifactId>
@ -123,7 +119,6 @@
org.wso2.carbon.context;version="${carbon.kernel.version.range}", org.wso2.carbon.context;version="${carbon.kernel.version.range}",
org.wso2.carbon.utils;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.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.core.*;resolution:=optional,
org.wso2.carbon.registry.common.*;version="${carbon.registry.imp.pkg.version.range}", org.wso2.carbon.registry.common.*;version="${carbon.registry.imp.pkg.version.range}",
org.wso2.carbon.registry.indexing.*; version="${carbon.registry.imp.pkg.version.range}", org.wso2.carbon.registry.indexing.*; version="${carbon.registry.imp.pkg.version.range}",

@ -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<String, Object> values;
private long timestamp;
public AnalyticsDataRecord() {
values = new HashMap<>();
}
public AnalyticsDataRecord(Map<String, Object> values) {
this.values = values;
}
public Map<String, Object> 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<String, Object> values) {
this.values = values;
}
public long getTimestamp() {
return this.timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
}

@ -25,7 +25,7 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File; import java.io.File;
public class DeviceAnalyticsUtil { public class DataPublisherUtil {
public static Document convertToDocument(File file) throws DataPublisherConfigurationException { public static Document convertToDocument(File file) throws DataPublisherConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

@ -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.config.AnalyticsConfiguration;
import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherAlreadyExistsException; 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.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.Registry;
import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.exceptions.RegistryException;
@ -71,7 +71,7 @@ public class DeviceDataPublisher {
return deviceDataPublisher; return deviceDataPublisher;
} }
private DeviceDataPublisher() { public DeviceDataPublisher() {
dataPublisherMap = new ConcurrentHashMap<>(); dataPublisherMap = new ConcurrentHashMap<>();
} }
@ -196,7 +196,7 @@ public class DeviceDataPublisher {
try { try {
PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
RegistryService registryService = DeviceAnalyticsDataHolder.getInstance().getRegistryService(); RegistryService registryService = DataPublisherDataHolder.getInstance().getRegistryService();
if (registryService != null) { if (registryService != null) {
Registry registry = registryService.getConfigSystemRegistry(tenantId); Registry registry = registryService.getConfigSystemRegistry(tenantId);
this.loadTenantRegistry(tenantId); this.loadTenantRegistry(tenantId);
@ -213,8 +213,8 @@ public class DeviceDataPublisher {
} }
private void loadTenantRegistry(int tenantId) throws RegistryException { private void loadTenantRegistry(int tenantId) throws RegistryException {
TenantRegistryLoader tenantRegistryLoader = DeviceAnalyticsDataHolder.getInstance().getTenantRegistryLoader(); TenantRegistryLoader tenantRegistryLoader = DataPublisherDataHolder.getInstance().getTenantRegistryLoader();
DeviceAnalyticsDataHolder.getInstance().getIndexLoaderService().loadTenantIndex(tenantId); DataPublisherDataHolder.getInstance().getIndexLoaderService().loadTenantIndex(tenantId);
tenantRegistryLoader.loadTenantRegistry(tenantId); tenantRegistryLoader.loadTenantRegistry(tenantId);
} }

@ -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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document; 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.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException;
import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.CarbonUtils;
@ -100,7 +100,7 @@ public class AnalyticsConfiguration {
public static void init() throws DataPublisherConfigurationException { public static void init() throws DataPublisherConfigurationException {
try { try {
File authConfig = new File(AnalyticsConfiguration.DEVICE_ANALYTICS_CONFIG_PATH); File authConfig = new File(AnalyticsConfiguration.DEVICE_ANALYTICS_CONFIG_PATH);
Document doc = DeviceAnalyticsUtil.convertToDocument(authConfig); Document doc = DataPublisherUtil.convertToDocument(authConfig);
/* Un-marshaling device analytics configuration */ /* Un-marshaling device analytics configuration */
JAXBContext ctx = JAXBContext.newInstance(AnalyticsConfiguration.class); JAXBContext ctx = JAXBContext.newInstance(AnalyticsConfiguration.class);

@ -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);
}
}

@ -18,36 +18,24 @@
*/ */
package org.wso2.carbon.device.mgt.analytics.data.publisher.internal; 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.RegistryService;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader;
public class DeviceAnalyticsDataHolder { public class DataPublisherDataHolder {
private static DeviceAnalyticsDataHolder thisInstance = new DeviceAnalyticsDataHolder(); private static DataPublisherDataHolder thisInstance = new DataPublisherDataHolder();
/**
* AnalyticsDataAPI is service used to retrieve data from DAS.
*/
private AnalyticsDataAPI analyticsDataAPI;
private TenantRegistryLoader tenantRegistryLoader; private TenantRegistryLoader tenantRegistryLoader;
private TenantIndexingLoader indexLoader; private TenantIndexingLoader indexLoader;
private RegistryService registryService; private RegistryService registryService;
private DeviceAnalyticsDataHolder() { private DataPublisherDataHolder() {
} }
public static DeviceAnalyticsDataHolder getInstance() { public static DataPublisherDataHolder getInstance() {
return thisInstance; return thisInstance;
} }
public AnalyticsDataAPI getAnalyticsDataAPI() {
return analyticsDataAPI;
}
public void setAnalyticsDataAPI(AnalyticsDataAPI analyticsDataAPI) {
this.analyticsDataAPI = analyticsDataAPI;
}
public void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader){ public void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader){
this.tenantRegistryLoader = tenantRegistryLoader; this.tenantRegistryLoader = tenantRegistryLoader;
} }

@ -23,23 +23,16 @@ import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration; import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext; 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.config.AnalyticsConfiguration;
import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsService; import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService;
import org.wso2.carbon.device.mgt.analytics.data.publisher.service.DeviceAnalyticsServiceImpl; 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.RegistryService;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; 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" * 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" * @scr.reference name="registry.service"
* interface="org.wso2.carbon.registry.core.service.RegistryService" * interface="org.wso2.carbon.registry.core.service.RegistryService"
* cardinality="1..1" * cardinality="1..1"
@ -58,10 +51,10 @@ import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader;
* bind="setIndexLoader" * bind="setIndexLoader"
* unbind="unsetIndexLoader" * unbind="unsetIndexLoader"
*/ */
public class DeviceAnalyticsServiceComponent { public class DataPublisherServiceComponent {
private ServiceRegistration analyticsServiceRef; private ServiceRegistration analyticsServiceRef;
private static Log log = LogFactory.getLog(DeviceAnalyticsServiceComponent.class); private static Log log = LogFactory.getLog(DataPublisherServiceComponent.class);
protected void activate(ComponentContext componentCtx) { protected void activate(ComponentContext componentCtx) {
try { try {
@ -72,7 +65,7 @@ public class DeviceAnalyticsServiceComponent {
BundleContext bundleCtx = componentCtx.getBundleContext(); BundleContext bundleCtx = componentCtx.getBundleContext();
this.analyticsServiceRef = this.analyticsServiceRef =
bundleCtx.registerService(DeviceAnalyticsService.class, new DeviceAnalyticsServiceImpl(), null); bundleCtx.registerService(EventsPublisherService.class, new EventsPublisherServiceImpl(), null);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Device management analytics bundle has been successfully initialized"); 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) { protected void setRegistryService(RegistryService registryService) {
if (registryService != null && log.isDebugEnabled()) { if (registryService != null && log.isDebugEnabled()) {
log.debug("Registry service initialized"); log.debug("Registry service initialized");
} }
DeviceAnalyticsDataHolder.getInstance().setRegistryService(registryService); DataPublisherDataHolder.getInstance().setRegistryService(registryService);
} }
protected void unsetRegistryService(RegistryService registryService) { protected void unsetRegistryService(RegistryService registryService) {
DeviceAnalyticsDataHolder.getInstance().setRegistryService(null); DataPublisherDataHolder.getInstance().setRegistryService(null);
} }
protected void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { protected void setTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) {
DeviceAnalyticsDataHolder.getInstance().setTenantRegistryLoader(tenantRegistryLoader); DataPublisherDataHolder.getInstance().setTenantRegistryLoader(tenantRegistryLoader);
} }
protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) { protected void unsetTenantRegistryLoader(TenantRegistryLoader tenantRegistryLoader) {
DeviceAnalyticsDataHolder.getInstance().setTenantRegistryLoader(null); DataPublisherDataHolder.getInstance().setTenantRegistryLoader(null);
} }
protected void setIndexLoader(TenantIndexingLoader indexLoader) { protected void setIndexLoader(TenantIndexingLoader indexLoader) {
if (indexLoader != null && log.isDebugEnabled()) { if (indexLoader != null && log.isDebugEnabled()) {
log.debug("IndexLoader service initialized"); log.debug("IndexLoader service initialized");
} }
DeviceAnalyticsDataHolder.getInstance().setIndexLoaderService(indexLoader); DataPublisherDataHolder.getInstance().setIndexLoaderService(indexLoader);
} }
protected void unsetIndexLoader(TenantIndexingLoader indexLoader) { protected void unsetIndexLoader(TenantIndexingLoader indexLoader) {
DeviceAnalyticsDataHolder.getInstance().setIndexLoaderService(null); DataPublisherDataHolder.getInstance().setIndexLoaderService(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<AnalyticsDataRecord> 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<SearchResultEntry> resultEntries = analyticsDataAPI.drillDownSearch(tenantId, drillDownRequest);
List<String> recordIds = getRecordIds(resultEntries);
AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds);
List<Record> 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<String> getRecordIds(List<SearchResultEntry> searchResults) {
List<String> ids = new ArrayList<>();
for (SearchResultEntry searchResult : searchResults) {
ids.add(searchResult.getId());
}
return ids;
}
private List<AnalyticsDataRecord> getAnalyticsDataRecords(List<Record> records) {
List<AnalyticsDataRecord> analyticsDataRecords = new ArrayList<>();
for (Record record : records) {
AnalyticsDataRecord analyticsDataRecord = new AnalyticsDataRecord(record.getValues());
analyticsDataRecords.add(analyticsDataRecord);
}
return analyticsDataRecords;
}
}

@ -18,16 +18,12 @@
*/ */
package org.wso2.carbon.device.mgt.analytics.data.publisher.service; 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.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. * 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. * 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, boolean publishEvent(String streamName, String version, Object[] metaDataArray, Object[] correlationDataArray,
Object[] payloadDataArray) throws DataPublisherConfigurationException; 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<AnalyticsDataRecord> getAllEventsForDevice(String tableName,
String query) throws DeviceManagementAnalyticsException;
} }

@ -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;
}
}
}

@ -90,10 +90,6 @@
<groupId>commons-lang.wso2</groupId> <groupId>commons-lang.wso2</groupId>
<artifactId>commons-lang</artifactId> <artifactId>commons-lang</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.api</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.wso2.carbon.registry</groupId> <groupId>org.wso2.carbon.registry</groupId>
<artifactId>org.wso2.carbon.registry.indexing</artifactId> <artifactId>org.wso2.carbon.registry.indexing</artifactId>

@ -18,13 +18,6 @@
package org.wso2.carbon.identity.jwt.client.extension; 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.codec.binary.Base64;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; 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.apache.http.message.BasicNameValuePair;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.KeyStoreManager;
import org.wso2.carbon.identity.jwt.client.extension.constant.JWTConstants; 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.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.dto.JWTConfig; 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.exception.JWTClientException;
import org.wso2.carbon.identity.jwt.client.extension.util.JWTClientUtil; import org.wso2.carbon.identity.jwt.client.extension.util.JWTClientUtil;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL; import java.net.URL;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; 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.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Random;
/** /**
* this class represents an implementation of Token Client which is based on JWT * this class represents an implementation of Token Client which is based on JWT
@ -69,12 +51,6 @@ import java.util.Random;
public class JWTClient { public class JWTClient {
private static Log log = LogFactory.getLog(JWTClient.class); 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; private JWTConfig jwtConfig;
public JWTClient(JWTConfig jwtConfig) { public JWTClient(JWTConfig jwtConfig) {
@ -87,13 +63,13 @@ public class JWTClient {
public AccessTokenInfo getAccessToken(String consumerKey, String consumerSecret, String username, String scopes) public AccessTokenInfo getAccessToken(String consumerKey, String consumerSecret, String username, String scopes)
throws JWTClientException { throws JWTClientException {
List<NameValuePair> params = new ArrayList<>(); List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair(GRANT_TYPE_PARAM_NAME, JWT_GRANT_TYPE)); params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, JWTConstants.JWT_GRANT_TYPE));
String assertion = generateSignedJWTAssertion(username); String assertion = JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig);
if (assertion == null) { if (assertion == null) {
throw new JWTClientException("JWT is not configured properly for user : " + username); throw new JWTClientException("JWT is not configured properly for user : " + username);
} }
params.add(new BasicNameValuePair(JWT_PARAM_NAME, assertion)); params.add(new BasicNameValuePair(JWTConstants.JWT_PARAM_NAME, assertion));
params.add(new BasicNameValuePair(SCOPE_PARAM_NAME, scopes)); params.add(new BasicNameValuePair(JWTConstants.SCOPE_PARAM_NAME, scopes));
return getTokenInfo(params, consumerKey, consumerSecret); return getTokenInfo(params, consumerKey, consumerSecret);
} }
@ -104,9 +80,9 @@ public class JWTClient {
String consumerKey, String consumerSecret) String consumerKey, String consumerSecret)
throws JWTClientException { throws JWTClientException {
List<NameValuePair> params = new ArrayList<>(); List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair(GRANT_TYPE_PARAM_NAME, REFRESH_TOKEN_GRANT_TYPE)); params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, JWTConstants.REFRESH_TOKEN_GRANT_TYPE));
params.add(new BasicNameValuePair(REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME, refreshToken)); params.add(new BasicNameValuePair(JWTConstants.REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME, refreshToken));
params.add(new BasicNameValuePair(SCOPE_PARAM_NAME, scopes)); params.add(new BasicNameValuePair(JWTConstants.SCOPE_PARAM_NAME, scopes));
return getTokenInfo(params, consumerKey, consumerSecret); return getTokenInfo(params, consumerKey, consumerSecret);
} }
@ -132,10 +108,10 @@ public class JWTClient {
JSONParser jsonParser = new JSONParser(); JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(response); JSONObject jsonObject = (JSONObject) jsonParser.parse(response);
AccessTokenInfo accessTokenInfo = new AccessTokenInfo(); AccessTokenInfo accessTokenInfo = new AccessTokenInfo();
accessTokenInfo.setAccess_token((String) jsonObject.get(JWTConstants.OAUTH_ACCESS_TOKEN)); accessTokenInfo.setAccessToken((String) jsonObject.get(JWTConstants.ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME));
accessTokenInfo.setRefresh_token((String) jsonObject.get(JWTConstants.OAUTH_REFRESH_TOKEN)); accessTokenInfo.setRefreshToken((String) jsonObject.get(JWTConstants.REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME));
accessTokenInfo.setExpires_in((Long) jsonObject.get(JWTConstants.OAUTH_EXPIRES_IN)); accessTokenInfo.setExpiresIn((Long) jsonObject.get(JWTConstants.OAUTH_EXPIRES_IN));
accessTokenInfo.setToken_type((String) jsonObject.get(JWTConstants.OAUTH_TOKEN_TYPE)); accessTokenInfo.setTokenType((String) jsonObject.get(JWTConstants.OAUTH_TOKEN_TYPE));
return accessTokenInfo; return accessTokenInfo;
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
throw new JWTClientException("Invalid URL for token endpoint " + jwtConfig.getTokenEndpoint(), 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())); 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<String> 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;
}
} }

@ -21,8 +21,15 @@ package org.wso2.carbon.identity.jwt.client.extension.constant;
* This holds the constants related JWT client component. * This holds the constants related JWT client component.
*/ */
public class JWTConstants { 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_EXPIRES_IN = "expires_in";
public static final String OAUTH_TOKEN_TYPE = "token_type"; 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";
} }

@ -23,40 +23,40 @@ package org.wso2.carbon.identity.jwt.client.extension.dto;
*/ */
public class AccessTokenInfo { public class AccessTokenInfo {
private String token_type; private String tokenType;
private long expires_in; private long expiresIn;
private String refresh_token; private String refreshToken;
private String access_token; private String accessToken;
public String getToken_type() { public String getTokenType() {
return token_type; return tokenType;
} }
public void setToken_type(String token_type) { public void setTokenType(String tokenType) {
this.token_type = token_type; this.tokenType = tokenType;
} }
public long getExpires_in() { public long getExpiresIn() {
return expires_in; return expiresIn;
} }
public void setExpires_in(long expres_in) { public void setExpiresIn(long expiresIn) {
this.expires_in = expres_in; this.expiresIn = expiresIn;
} }
public String getRefresh_token() { public String getRefreshToken() {
return refresh_token; return refreshToken;
} }
public void setRefresh_token(String refresh_token) { public void setRefreshToken(String refreshToken) {
this.refresh_token = refresh_token; this.refreshToken = refreshToken;
} }
public String getAccess_token() { public String getAccessToken() {
return access_token; return accessToken;
} }
public void setAccess_token(String access_token) { public void setAccessToken(String accessToken) {
this.access_token = access_token; this.accessToken = accessToken;
} }
} }

@ -20,7 +20,11 @@ package org.wso2.carbon.identity.jwt.client.extension.internal;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.ComponentContext; 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.identity.jwt.client.extension.util.JWTClientUtil;
import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.service.RegistryService;
@ -66,11 +70,16 @@ public class JWTClientExtensionServiceComponent {
log.debug("Initializing jwt extension bundle"); log.debug("Initializing jwt extension bundle");
} }
try { try {
JWTClientUtil.initialize(); JWTClientManagerService jwtClientManagerService = new JWTClientManagerServiceImpl();
JWTClientUtil.initialize(jwtClientManagerService);
BundleContext bundleContext = componentContext.getBundleContext();
bundleContext.registerService(JWTClientManagerService.class.getName(), jwtClientManagerService, null);
} catch (RegistryException e) { } catch (RegistryException e) {
log.error("Failed loading the jwt config from registry.", e); log.error("Failed loading the jwt config from registry.", e);
} catch (IOException e) { } catch (IOException e) {
log.error("Failed loading the jwt config from the file system.", 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);
} }
} }

@ -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;
}

@ -16,12 +16,15 @@
* under the License. * 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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.PrivilegedCarbonContext; 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.dto.JWTConfig;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientAlreadyExistsException; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientAlreadyExistsException;
import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientConfigurationException; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientConfigurationException;
@ -36,42 +39,44 @@ import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap; 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<String, JWTClient> jwtClientMap; private static Map<String, JWTClient> jwtClientMap;
private static JWTClientManager jwtClientCreator; private static final Log log = LogFactory.getLog(JWTClientManagerServiceImpl.class);
private static final Log log = LogFactory.getLog(JWTClientManager.class);
private static final String TENANT_JWT_CONFIG_LOCATION = "/jwt-config/jwt.properties"; 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<>(); jwtClientMap = new ConcurrentHashMap<>();
} }
/** /**
* this return the jwt based token client to generate token for the tenant. * this return the jwt based token client to generate token for the tenant.
*/ */
@Override
public JWTClient getJWTClient() throws JWTClientException { public JWTClient getJWTClient() throws JWTClientException {
String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); 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. //Get jwt client which has been registered for the tenant.
JWTClient jwtClient = getJWTClient(tenantDomain); JWTClient jwtClient = getJWTClient(tenantDomain);
if (jwtClient == null) { if (jwtClient == null) {
//Create new jwt client for the tenant. //Create a new jwt client for the tenant.
try { 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); jwtClient = new JWTClient(jwtConfig);
addJWTClient(tenantDomain, jwtClient); addJWTClient(tenantDomain, jwtClient);
} catch (JWTClientAlreadyExistsException e) { } catch (JWTClientAlreadyExistsException e) {
@ -85,6 +90,31 @@ public class JWTClientManager {
return jwtClient; 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. * 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 * @throws JWTClientAlreadyExistsException - If a jwt client has already been registered under the tenantdomain
*/ */
private void addJWTClient(String tenantDomain, JWTClient jwtClient) throws JWTClientAlreadyExistsException { private void addJWTClient(String tenantDomain, JWTClient jwtClient) throws JWTClientAlreadyExistsException {
if (jwtClientMap.containsKey(tenantDomain)) { synchronized (jwtClientMap) {
throw new JWTClientAlreadyExistsException("A jwt client has already been created for the tenant " + tenantDomain); 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. * Retrieve JWT configs from registry.
*/ */
private Properties getJWTConfig(int tenantId) throws JWTClientConfigurationException { private Properties getJWTConfigProperties(int tenantId) throws JWTClientConfigurationException {
try { try {
Resource config = JWTClientUtil.getConfigRegistryResourceContent(tenantId, TENANT_JWT_CONFIG_LOCATION); Resource config = JWTClientUtil.getConfigRegistryResourceContent(tenantId, TENANT_JWT_CONFIG_LOCATION);
Properties properties = new Properties(); Properties properties = null;
if(config != null) { if (config != null) {
properties = new Properties();
properties.load(config.getContentStream()); properties.load(config.getContentStream());
} else {
throw new JWTClientConfigurationException("Failed to load jwt configuration for tenant id : " + tenantId);
} }
return properties; return properties;
} catch (RegistryException e) { } catch (RegistryException e) {

@ -17,7 +17,13 @@
*/ */
package org.wso2.carbon.identity.jwt.client.extension.util; 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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse; 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.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext; 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.identity.jwt.client.extension.internal.JWTClientExtensionDataHolder;
import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.Resource; 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.RegistryService;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.CarbonUtils;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; 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. * 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 JWT_CONFIG_FILE_NAME = "jwt.properties";
private static final String SUPERTENANT_JWT_CONFIG_LOCATION = private static final String SUPERTENANT_JWT_CONFIG_LOCATION =
CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + JWT_CONFIG_FILE_NAME; CarbonUtils.getEtcCarbonConfigDirPath() + File.separator + JWT_CONFIG_FILE_NAME;
/** /**
* Return a http client instance * Return a http client instance
*
* @param protocol- service endpoint protocol http/https * @param protocol- service endpoint protocol http/https
* @return * @return
*/ */
@ -96,12 +120,14 @@ public class JWTClientUtil {
} }
} }
public static void initialize() throws RegistryException, IOException { public static void initialize(JWTClientManagerService jwtClientManagerService)
Resource resource = getConfigRegistryResourceContent(MultitenantConstants.SUPER_TENANT_ID, TENANT_JWT_CONFIG_LOCATION); throws RegistryException, IOException, JWTClientConfigurationException {
if (resource == null) { File configFile = new File(SUPERTENANT_JWT_CONFIG_LOCATION);
File configFile = new File(SUPERTENANT_JWT_CONFIG_LOCATION); if (configFile.exists()) {
String contents = FileUtils.readFileToString(configFile, "UTF-8"); InputStream propertyStream = configFile.toURI().toURL().openStream();
addJWTConfigResourceToRegistry(MultitenantConstants.SUPER_TENANT_ID, contents); 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. * 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 * @return the config for tenant
* @throws RegistryException * @throws RegistryException
*/ */
@ -161,8 +187,96 @@ public class JWTClientUtil {
} }
private static void loadTenantRegistry(int tenantId) throws RegistryException { private static void loadTenantRegistry(int tenantId) throws RegistryException {
TenantRegistryLoader tenantRegistryLoader = JWTClientExtensionDataHolder.getInstance().getTenantRegistryLoader(); TenantRegistryLoader tenantRegistryLoader =
JWTClientExtensionDataHolder.getInstance().getTenantRegistryLoader();
JWTClientExtensionDataHolder.getInstance().getIndexLoaderService().loadTenantIndex(tenantId); JWTClientExtensionDataHolder.getInstance().getIndexLoaderService().loadTenantIndex(tenantId);
tenantRegistryLoader.loadTenantRegistry(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<String> 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;
}
} }

@ -45,8 +45,6 @@ public class WebappAuthenticationValve extends CarbonTomcatValve {
return; return;
} }
WebappAuthenticator authenticator = WebappAuthenticatorFactory.getAuthenticator(request); WebappAuthenticator authenticator = WebappAuthenticatorFactory.getAuthenticator(request);
if (authenticator == null) { if (authenticator == null) {
String msg = "Failed to load an appropriate authenticator to authenticate the request"; String msg = "Failed to load an appropriate authenticator to authenticate the request";

@ -1,44 +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.
-->
<IdentityProvider>
<IdentityProviderName>CDMF_DEFAULT_IDP</IdentityProviderName>
<DisplayName>CDMF_DEFAULT_IDP</DisplayName>
<IdentityProviderDescription></IdentityProviderDescription>
<Alias>https://localhost:9443/oauth2/token</Alias>
<IsPrimary>true</IsPrimary>
<IsFederationHub></IsFederationHub>
<HomeRealmId></HomeRealmId>
<ProvisioningRole></ProvisioningRole>
<FederatedAuthenticatorConfigs></FederatedAuthenticatorConfigs>
<DefaultAuthenticatorConfig>
</DefaultAuthenticatorConfig>
<ProvisioningConnectorConfigs>
<!--<ProvisioningConnectorConfig>
<ProvisioningProperties>
</ProvisioningProperties>
</ProvisioningConnectorConfig>-->
</ProvisioningConnectorConfigs>
<!--<DefaultProvisioningConnectorConfig></DefaultProvisioningConnectorConfig>-->
<ClaimConfig></ClaimConfig>
<Certificate>
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
</Certificate>
<PermissionAndRoleConfig></PermissionAndRoleConfig>
<JustInTimeProvisioningConfig></JustInTimeProvisioningConfig>
</IdentityProvider>

@ -41,7 +41,7 @@ skew=0
#jti=token123 #jti=token123
#KeyStore to cryptographic credentials #KeyStore to cryptographic credentials
#KeyStore=src/main/resources/wso2carbon.jks #KeyStore=repository/resources/security/wso2carbon.jks
#Password of the KeyStore #Password of the KeyStore
#KeyStorePassword=wso2carbon #KeyStorePassword=wso2carbon
@ -52,3 +52,6 @@ skew=0
#Private key password to retrieve the private key used to sign #Private key password to retrieve the private key used to sign
#AuthnRequest and LogoutRequest messages #AuthnRequest and LogoutRequest messages
#PrivateKeyPassword=wso2carbon #PrivateKeyPassword=wso2carbon
#this will be used as the default IDP config if there isn't any config available for tenants.
default-jwt-client=true

@ -1,3 +1,2 @@
instructions.configure = \ 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}/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);\

@ -1385,13 +1385,6 @@
<version>${carbon.analytics.common.version}</version> <version>${carbon.analytics.common.version}</version>
</dependency> </dependency>
<!-- Carbon Analytics -->
<dependency>
<groupId>org.wso2.carbon.analytics</groupId>
<artifactId>org.wso2.carbon.analytics.api</artifactId>
<version>${carbon.analytics.version}</version>
</dependency>
<!-- Carbon Registry --> <!-- Carbon Registry -->
<dependency> <dependency>
<groupId>org.wso2.carbon.registry</groupId> <groupId>org.wso2.carbon.registry</groupId>
@ -1744,10 +1737,6 @@
<carbon.analytics.common.version>5.0.11</carbon.analytics.common.version> <carbon.analytics.common.version>5.0.11</carbon.analytics.common.version>
<carbon.analytics.common.version.range>[5.0.11,6.0.0)</carbon.analytics.common.version.range> <carbon.analytics.common.version.range>[5.0.11,6.0.0)</carbon.analytics.common.version.range>
<!-- Carbon Analytics -->
<carbon.analytics.version>1.0.5</carbon.analytics.version>
<carbon.analytics.version.range>[1.0.5,2.0.0]</carbon.analytics.version.range>
<!-- Carbon Registry --> <!-- Carbon Registry -->
<carbon.registry.version>4.4.8</carbon.registry.version> <carbon.registry.version>4.4.8</carbon.registry.version>
<carbon.registry.imp.pkg.version.range>[4.4.8, 5.0.0)</carbon.registry.imp.pkg.version.range> <carbon.registry.imp.pkg.version.range>[4.4.8, 5.0.0)</carbon.registry.imp.pkg.version.range>

Loading…
Cancel
Save