diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/pom.xml
new file mode 100644
index 0000000000..6715d66cbe
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/pom.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+ apimgt-extensions
+ org.wso2.carbon.devicemgt
+ 1.1.0-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ org.wso2.carbon.apimgt.annotations
+ 1.1.0-SNAPSHOT
+ bundle
+ WSO2 Carbon - API Management Annotations
+ WSO2 Carbon - API Management Custom Annotation Module
+ http://wso2.org
+
+
+
+ org.eclipse.osgi
+ org.eclipse.osgi
+
+
+ org.eclipse.osgi
+ org.eclipse.osgi.services
+
+
+ org.wso2.carbon
+ org.wso2.carbon.logging
+
+
+ javax.ws.rs
+ jsr311-api
+
+
+
+
+
+ org.apache.felix
+ maven-scr-plugin
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ 1.4.0
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+ ${carbon.device.mgt.version}
+ API Management Extentions - Custom Annotations
+
+ org.wso2.carbon.apimgt.annotations.*
+
+
+ org.osgi.framework,
+ org.osgi.service.component,
+ org.apache.commons.logging,
+ javax.servlet,
+ javax.xml.*,
+ org.apache.commons.lang,
+
+
+ scribe;scope=compile|runtime;inline=false;
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/src/main/java/org/wso2/carbon/apimgt/annotations/api/API.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/src/main/java/org/wso2/carbon/apimgt/annotations/api/API.java
new file mode 100644
index 0000000000..04ecd9ed70
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/src/main/java/org/wso2/carbon/apimgt/annotations/api/API.java
@@ -0,0 +1,36 @@
+/*
+ * 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.apimgt.annotations.api;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface API {
+
+ String name();
+
+ String version();
+
+ String context();
+
+ String[] tags();
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml
new file mode 100644
index 0000000000..bfe5a9177b
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml
@@ -0,0 +1,171 @@
+
+
+
+
+
+ apimgt-extensions
+ org.wso2.carbon.devicemgt
+ 1.1.0-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ 1.1.0-SNAPSHOT
+ org.wso2.carbon.apimgt.application.extension.api
+ war
+ WSO2 Carbon - API Application Management API
+ This module provides capability to create api manager application.
+ http://wso2.org
+
+
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxws
+ provided
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxrs
+ provided
+
+
+ org.apache.cxf
+ cxf-rt-transports-http
+ provided
+
+
+
+
+ org.codehaus.jackson
+ jackson-core-asl
+
+
+ org.codehaus.jackson
+ jackson-jaxrs
+
+
+ javax
+ javaee-web-api
+ provided
+
+
+ javax.ws.rs
+ jsr311-api
+ provided
+
+
+ commons-httpclient.wso2
+ commons-httpclient
+ provided
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+ provided
+
+
+ org.bouncycastle.wso2
+ bcprov-jdk15on
+
+
+ org.wso2.carbon
+ org.wso2.carbon.user.api
+
+
+ org.wso2.carbon
+ org.wso2.carbon.queuing
+
+
+ org.wso2.carbon
+ org.wso2.carbon.base
+
+
+ org.apache.axis2.wso2
+ axis2
+
+
+ org.igniterealtime.smack.wso2
+ smack
+
+
+ org.igniterealtime.smack.wso2
+ smackx
+
+
+ jaxen
+ jaxen
+
+
+ commons-fileupload.wso2
+ commons-fileupload
+
+
+ org.apache.ant.wso2
+ ant
+
+
+ org.apache.ant.wso2
+ ant
+
+
+ commons-httpclient.wso2
+ commons-httpclient
+
+
+ org.eclipse.equinox
+ javax.servlet
+
+
+ org.wso2.carbon
+ org.wso2.carbon.registry.api
+
+
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.apimgt.application.extension
+ provided
+
+
+
+
+
+
+ maven-compiler-plugin
+
+ UTF-8
+
+ ${wso2.maven.compiler.target}
+
+
+
+ maven-war-plugin
+ 2.2
+
+ ${project.artifactId}
+
+
+
+
+
+
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationService.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationService.java
new file mode 100644
index 0000000000..f6404de2d6
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationService.java
@@ -0,0 +1,58 @@
+/*
+ * 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.apimgt.application.extension.api;
+
+import org.wso2.carbon.apimgt.application.extension.api.util.RegistrationProfile;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ * This is the application registration service that exposed for apimApplicationRegistration
+ */
+public interface ApiApplicationRegistrationService {
+
+ /**
+ * This method is used to register an APIM application for tenant domain.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ Response register(@PathParam("tenantDomain") String tenantDomain,
+ @QueryParam("applicationName") String applicationName);
+
+ /**
+ * This method is used to register api application
+ *
+ * @param registrationProfile contains the necessary attributes that are needed in order to register an app.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Consumes(MediaType.APPLICATION_JSON)
+ Response register(RegistrationProfile registrationProfile);
+
+ @DELETE
+ Response unregister(@QueryParam("applicationName") String applicationName);
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java
new file mode 100644
index 0000000000..00f537c086
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java
@@ -0,0 +1,129 @@
+/*
+ * 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.apimgt.application.extension.api;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.simple.JSONObject;
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.apimgt.application.extension.api.util.RegistrationProfile;
+import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants;
+import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
+import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.apimgt.application.extension.api.util.APIUtil;
+import org.wso2.carbon.user.api.UserStoreException;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+
+
+public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegistrationService {
+ private static final Log log = LogFactory.getLog(ApiApplicationRegistrationServiceImpl.class);
+
+ @Path("register/tenants/{tenantDomain}")
+ @POST
+ public Response register(@PathParam("tenantDomain") String tenantDomain,
+ @QueryParam("applicationName") String applicationName) {
+ Response response;
+ try {
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true);
+ if (PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId() == -1) {
+ String msg = "Invalid tenant domain : " + tenantDomain;
+ response = Response.status(Response.Status.NOT_ACCEPTABLE).entity(msg).build();
+ }
+ String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm()
+ .getRealmConfiguration().getAdminUserName();
+ PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(username);
+ APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
+ ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
+ applicationName, ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username, false);
+ return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build();
+ } catch (APIManagerException e) {
+ String msg = "Error occurred while registering an application '" + applicationName + "'";
+ log.error(msg, e);
+ response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
+ } catch (UserStoreException e) {
+ String msg = "Failed to retrieve the tenant" + tenantDomain + "'";
+ log.error(msg, e);
+ response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ return response;
+ }
+
+ @Path("register")
+ @POST
+ public Response register(RegistrationProfile registrationProfile) {
+ Response response;
+ try {
+ String username = APIUtil.getAuthenticatedUser();
+ APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
+ if (registrationProfile.isMappingAnExistingOAuthApp()) {
+ JSONObject jsonStringObject = new JSONObject();
+ jsonStringObject.put(ApiApplicationConstants.JSONSTRING_USERNAME_TAG, username);
+ jsonStringObject.put(ApiApplicationConstants.JSONSTRING_KEY_TYPE_TAG,
+ ApiApplicationConstants.DEFAULT_TOKEN_TYPE);
+ jsonStringObject.put(ApiApplicationConstants.OAUTH_CLIENT_ID, registrationProfile.getConsumerKey());
+ jsonStringObject.put(ApiApplicationConstants.OAUTH_CLIENT_SECRET,
+ registrationProfile.getConsumerSecret());
+ jsonStringObject.put(ApiApplicationConstants.JSONSTRING_VALIDITY_PERIOD_TAG,
+ ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD);
+ apiManagementProviderService.registerExistingOAuthApplicationToAPIApplication(
+ jsonStringObject.toJSONString(), registrationProfile.getApplicationName(),
+ registrationProfile.getConsumerKey(), username, registrationProfile.isAllowedToAllDomains());
+ return Response.status(Response.Status.ACCEPTED).entity("OAuth App is mapped as APIM App").build();
+ } else {
+ ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys(
+ registrationProfile.getApplicationName(), registrationProfile.getTags(),
+ ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username, false);
+ return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build();
+ }
+ } catch (APIManagerException e) {
+ String msg = "Error occurred while registering an application '"
+ + registrationProfile.getApplicationName() + "'";
+ log.error(msg, e);
+ response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
+ }
+ return response;
+ }
+
+ @Path("unregister")
+ @DELETE
+ public Response unregister(@QueryParam("applicationName") String applicationName) {
+ Response response;
+ try {
+ String username = APIUtil.getAuthenticatedUser();
+ APIManagementProviderService apiManagementProviderService = APIUtil.getAPIManagementProviderService();
+ apiManagementProviderService.removeAPIApplication(applicationName, username);
+ return Response.status(Response.Status.ACCEPTED).build();
+ } catch (APIManagerException e) {
+ String msg = "Error occurred while removing the application '" + applicationName;
+ log.error(msg, e);
+ response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
+ }
+ return response;
+ }
+}
\ No newline at end of file
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java
new file mode 100644
index 0000000000..b15bcd1944
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/APIUtil.java
@@ -0,0 +1,60 @@
+/*
+ * 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.apimgt.application.extension.api.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+
+/**
+ * This class provides utility functions used by REST-API.
+ */
+public class APIUtil {
+
+ private static Log log = LogFactory.getLog(APIUtil.class);
+
+ public static String getAuthenticatedUser() {
+ PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ String username = threadLocalCarbonContext.getUsername();
+ String tenantDomain = threadLocalCarbonContext.getTenantDomain();
+ if (username.endsWith(tenantDomain)) {
+ return username.substring(0, username.lastIndexOf("@"));
+ }
+ return username;
+ }
+
+ public static String getTenantDomainOftheUser() {
+ PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ String tenantDomain = threadLocalCarbonContext.getTenantDomain();
+ return tenantDomain;
+ }
+
+ public static APIManagementProviderService getAPIManagementProviderService() {
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ APIManagementProviderService apiManagementProviderService =
+ (APIManagementProviderService) ctx.getOSGiService(APIManagementProviderService.class, null);
+ if (apiManagementProviderService == null) {
+ String msg = "API management provider service has not initialized.";
+ log.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ return apiManagementProviderService;
+ }
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/RegistrationProfile.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/RegistrationProfile.java
new file mode 100644
index 0000000000..c0d231039c
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/RegistrationProfile.java
@@ -0,0 +1,92 @@
+/*
+ * 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.apimgt.application.extension.api.util;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * DTO class to be used when registering an ApiM application.
+ */
+@XmlRootElement
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RegistrationProfile {
+
+ @XmlElement(required = true)
+ private String applicationName;
+ @XmlElement(required = true)
+ private String tags[];
+ @XmlElement(required = true)
+ private boolean isAllowedToAllDomains;
+ @XmlElement(required = true)
+ private boolean isMappingAnExistingOAuthApp;
+ private String consumerKey;
+ private String consumerSecret;
+
+ public String getApplicationName() {
+ return applicationName;
+ }
+
+ public void setApiApplicationName(String apiApplicationName) {
+ this.applicationName = apiApplicationName;
+ }
+
+ public String[] getTags() {
+ return tags;
+ }
+
+ public void setTags(String[] tags) {
+ this.tags = tags;
+ }
+
+ public boolean isAllowedToAllDomains() {
+ return isAllowedToAllDomains;
+ }
+
+ public void setIsAllowedToAllDomains(boolean isAllowedToAllDomains) {
+ this.isAllowedToAllDomains = isAllowedToAllDomains;
+ }
+
+ public boolean isMappingAnExistingOAuthApp() {
+ return isMappingAnExistingOAuthApp;
+ }
+
+ public void setIsMappingAnExistingOAuthApp(boolean isMappingAnExistingOAuthApp) {
+ this.isMappingAnExistingOAuthApp = isMappingAnExistingOAuthApp;
+ }
+
+ public String getConsumerKey() {
+ return consumerKey;
+ }
+
+ public void setConsumerKey(String consumerKey) {
+ this.consumerKey = consumerKey;
+ }
+
+ public String getConsumerSecret() {
+ return consumerSecret;
+ }
+
+ public void setConsumerSecret(String consumerSecret) {
+ this.consumerSecret = consumerSecret;
+ }
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/permissions.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/permissions.xml
new file mode 100644
index 0000000000..104c34fe3e
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/permissions.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+ Register tenant specific application
+ /permission/super admin
+ /register/tenants/*
+ POST
+ super_admin_user
+
+
+ Register application
+ /device-mgt/api/application/add
+ /register
+ POST
+ application_user
+
+
+ Delete application
+ /device-mgt/api/application/remove
+ /unregister
+ DELETE
+ application_user
+
+
\ No newline at end of file
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/webapp-classloading.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/webapp-classloading.xml
new file mode 100644
index 0000000000..b410b42670
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/META-INF/webapp-classloading.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+ false
+
+
+ CXF,Carbon
+
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/WEB-INF/cxf-servlet.xml
new file mode 100644
index 0000000000..c9c72c4ad6
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/WEB-INF/cxf-servlet.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/WEB-INF/web.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..7aaaf3002d
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,52 @@
+
+
+
+
+ WSO2 IoT Server
+ WSO2 IoT Server
+
+
+ CXFServlet
+ org.apache.cxf.transport.servlet.CXFServlet
+ 1
+
+
+
+ CXFServlet
+ /*
+
+
+ isAdminService
+ false
+
+
+ doAuthentication
+ true
+
+
+
+
+ managed-api-enabled
+ false
+
+
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml
new file mode 100644
index 0000000000..3e2d879c8b
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+ apimgt-extensions
+ org.wso2.carbon.devicemgt
+ 1.1.0-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ 1.1.0-SNAPSHOT
+ org.wso2.carbon.apimgt.application.extension
+ bundle
+ WSO2 Carbon - API Application Management
+ This module provides capability to create api manager application.
+ http://wso2.org
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.registry.core
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+
+
+ org.wso2.carbon
+ org.wso2.carbon.logging
+
+
+ org.wso2.carbon.apimgt
+ org.wso2.carbon.apimgt.impl
+
+
+ org.wso2.carbon.apimgt
+ org.wso2.carbon.apimgt.api
+
+
+ com.googlecode.json-simple.wso2
+ json-simple
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ **/Abstract*
+
+
+
+
+ org.apache.felix
+ maven-scr-plugin
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+ ${carbon.device.mgt.version}
+ API Management Application Bundle
+ org.wso2.carbon.apimgt.application.extension.internal
+
+ org.osgi.framework,
+ org.osgi.service.component,
+ org.apache.commons.logging.*,
+ org.wso2.carbon.user.core.*,
+ org.wso2.carbon.apimgt.api;version="${carbon.api.mgt.version.range}",
+ org.wso2.carbon.apimgt.api.model;version="${carbon.api.mgt.version.range}",
+ org.wso2.carbon.apimgt.impl;version="${carbon.api.mgt.version.range}",
+ org.wso2.carbon.user.api,
+ org.wso2.carbon.utils.multitenancy,
+ org.json.simple,
+ org.wso2.carbon.context
+
+
+ !org.wso2.carbon.apimgt.application.extension.internal,
+ org.wso2.carbon.apimgt.application.extension.*
+
+
+
+
+
+
+
+
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java
new file mode 100644
index 0000000000..643d66c23d
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java
@@ -0,0 +1,70 @@
+/*
+ * 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.apimgt.application.extension;
+
+
+import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
+import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
+
+/**
+ * This comprise on operation that is been done with api manager from CDMF. This service needs to be implemented in APIM.
+ */
+public interface APIManagementProviderService {
+
+ /**
+ * Generate and retreive application keys. if the application does exist then
+ * create it and subscribe to apis that are grouped with the tags.
+ *
+ * @param apiApplicationName name of the application.
+ * @param tags tags of the apis that application needs to be subscribed.
+ * @param keyType of the application.
+ * @param username to whom the application is created
+ * @return consumerkey and secrete of the created application.
+ * @throws APIManagerException
+ */
+ ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName, String tags[],
+ String keyType, String username, boolean isAllowedAllDomains)
+ throws APIManagerException;
+
+ /**
+ * Generate and retreive application keys. if the application does exist then
+ * create it and subscribe to all apis.
+ *
+ * @param apiApplicationName name of the application.
+ * @param keyType of the application.
+ * @param username to whom the application is created
+ * @return consumerkey and secrete of the created application.
+ * @throws APIManagerException
+ */
+ ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName, String keyType,
+ String username, boolean isAllowedAllDomains)
+ throws APIManagerException;
+
+ /**
+ * Register existing Oauth application as apim application.
+ */
+ void registerExistingOAuthApplicationToAPIApplication(String jsonString, String applicationName, String clientId,
+ String username, boolean isAllowedAllDomains)
+ throws APIManagerException;
+
+ /**
+ * Remove APIM Application.
+ */
+ void removeAPIApplication(String applicationName, String username) throws APIManagerException;
+
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java
new file mode 100644
index 0000000000..7a2af128d8
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java
@@ -0,0 +1,406 @@
+/*
+ * 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.apimgt.application.extension;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.simple.JSONObject;
+import org.wso2.carbon.apimgt.api.APIConsumer;
+import org.wso2.carbon.apimgt.api.APIManagementException;
+import org.wso2.carbon.apimgt.api.model.API;
+import org.wso2.carbon.apimgt.api.model.APIIdentifier;
+import org.wso2.carbon.apimgt.api.model.APIKey;
+import org.wso2.carbon.apimgt.api.model.Application;
+import org.wso2.carbon.apimgt.api.model.SubscribedAPI;
+import org.wso2.carbon.apimgt.api.model.Subscriber;
+import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants;
+import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey;
+import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
+import org.wso2.carbon.apimgt.application.extension.util.APIManagerUtil;
+import org.wso2.carbon.apimgt.impl.APIConstants;
+import org.wso2.carbon.apimgt.impl.APIManagerFactory;
+import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
+import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This class represents an implementation of APIManagementProviderService.
+ */
+public class APIManagementProviderServiceImpl implements APIManagementProviderService {
+
+ private static final Log log = LogFactory.getLog(APIManagementProviderServiceImpl.class);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName, String keyType,
+ String username, boolean isAllowedAllDomains)
+ throws APIManagerException {
+ try {
+ APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
+ String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
+ int applicationId = createApplicationAndSubscribeToAllAPIs(apiApplicationName, username);
+ Application[] applications = apiConsumer.getApplications(apiConsumer.getSubscriber(username), 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 " + apiApplicationName +
+ " 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) {
+ ApiApplicationKey apiApplicationKey = new ApiApplicationKey();
+ apiApplicationKey.setConsumerKey(retrievedApiApplicationKey.getConsumerKey());
+ apiApplicationKey.setConsumerSecret(retrievedApiApplicationKey.getConsumerSecret());
+ return apiApplicationKey;
+ }
+ String[] allowedDomains = new String[1];
+ if (isAllowedAllDomains) {
+ allowedDomains[0] = ApiApplicationConstants.ALLOWED_DOMAINS;
+ } else {
+ allowedDomains[0] = APIManagerUtil.getTenantDomain();
+ }
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(ApiApplicationConstants.JSONSTRING_USERNAME_TAG, username);
+ String ownerJsonString = jsonObject.toJSONString();
+ Map keyDetails = apiConsumer.requestApprovalForApplicationRegistration(username,
+ apiApplicationName,
+ keyType, "",
+ allowedDomains,
+ ApiApplicationConstants.DEFAULT_VALIDITY_PERIOD,
+ "null", groupId,
+ ownerJsonString);
+ ApiApplicationKey apiApplicationKey = new ApiApplicationKey();
+ apiApplicationKey.setConsumerKey((String) keyDetails.get(APIConstants.FrontEndParameterNames
+ .CONSUMER_KEY));
+ apiApplicationKey.setConsumerSecret((String) keyDetails.get(
+ APIConstants.FrontEndParameterNames.CONSUMER_SECRET));
+ return apiApplicationKey;
+ } catch (APIManagementException e) {
+ throw new APIManagerException("Failed to register a api application : " + apiApplicationName, e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void registerExistingOAuthApplicationToAPIApplication(String jsonString, String applicationName,
+ String clientId, String username,
+ boolean isAllowedAllDomains)
+ throws APIManagerException {
+ try {
+ APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
+ if (apiConsumer != null) {
+ String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
+ createApplication(apiConsumer, applicationName, username, groupId);
+ String[] allowedDomains = new String[1];
+ if (isAllowedAllDomains) {
+ allowedDomains[0] = ApiApplicationConstants.ALLOWED_DOMAINS;
+ } else {
+ allowedDomains[0] = APIManagerUtil.getTenantDomain();
+ }
+ apiConsumer.mapExistingOAuthClient(jsonString, username, clientId, applicationName,
+ ApiApplicationConstants.DEFAULT_TOKEN_TYPE, allowedDomains);
+ }
+ } catch (APIManagementException e) {
+ throw new APIManagerException(
+ "Failed registering the OAuth app [ clientId " + clientId + " ] with api manager application", e);
+ }
+ }
+
+ @Override
+ public void removeAPIApplication(String applicationName, String username) throws APIManagerException {
+ try {
+ APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
+ if (apiConsumer != null) {
+ String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
+ Application[] applications = apiConsumer.getApplications(new Subscriber(username), groupId);
+ for (Application application : applications) {
+ if (application.getName().equals(applicationName)) {
+ apiConsumer.removeApplication(application);
+ break;
+ }
+ }
+ }
+ } catch (APIManagementException e) {
+ throw new APIManagerException(
+ "Failed to remove the application [ application name " + applicationName + " ]", e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName, String tags[],
+ String keyType, String username,
+ boolean isAllowedAllDomains)
+ throws APIManagerException {
+ try {
+ APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
+ String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
+ int applicationId = createApplicationAndSubscribeToAPIs(apiApplicationName, tags, username);
+ Application[] applications = apiConsumer.getApplications(apiConsumer.getSubscriber(username), 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 " + apiApplicationName + " 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) {
+ ApiApplicationKey apiApplicationKey = new ApiApplicationKey();
+ apiApplicationKey.setConsumerKey(retrievedApiApplicationKey.getConsumerKey());
+ apiApplicationKey.setConsumerSecret(retrievedApiApplicationKey.getConsumerSecret());
+ return apiApplicationKey;
+ }
+ String[] allowedDomains = new String[1];
+ if (isAllowedAllDomains) {
+ allowedDomains[0] = ApiApplicationConstants.ALLOWED_DOMAINS;
+ } else {
+ allowedDomains[0] = APIManagerUtil.getTenantDomain();
+ }
+ String validityTime = "3600";
+ String ownerJsonString = "{\"username\":\"" + username + "\"}";
+ Map keyDetails = apiConsumer.requestApprovalForApplicationRegistration(username,
+ apiApplicationName,
+ keyType, "",
+ allowedDomains,
+ validityTime,
+ "null",
+ groupId,
+ ownerJsonString);
+ ApiApplicationKey apiApplicationKey = new ApiApplicationKey();
+ apiApplicationKey.setConsumerKey((String) keyDetails.get(APIConstants.FrontEndParameterNames
+ .CONSUMER_KEY));
+ apiApplicationKey.setConsumerSecret((String) keyDetails.get(
+ APIConstants.FrontEndParameterNames.CONSUMER_SECRET));
+ return apiApplicationKey;
+ } catch (APIManagementException e) {
+ throw new APIManagerException("Failed to register a api application : " + apiApplicationName, e);
+ }
+ }
+
+ private int createApplication(APIConsumer apiConsumer, String applicationName, String username, String groupId)
+ throws APIManagerException {
+ try {
+ if (apiConsumer != null) {
+ if (apiConsumer.getSubscriber(username) == null) {
+ String tenantDomain = MultitenantUtils.getTenantDomain(username);
+ addSubscriber(username, "", groupId, APIManagerUtil.getTenantId(tenantDomain));
+ }
+ Application application = apiConsumer.getApplicationsByName(username, applicationName, groupId);
+ if (application == null) {
+ Subscriber subscriber = apiConsumer.getSubscriber(username);
+ application = new Application(applicationName, subscriber);
+ application.setTier(ApiApplicationConstants.DEFAULT_TIER);
+ application.setGroupId(groupId);
+ return apiConsumer.addApplication(application, username);
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Application [" + applicationName + "] already exists for Subscriber [" + username +
+ "]");
+ }
+ return application.getId();
+ }
+ } else {
+ throw new APIManagerException("Failed to retrieve the api consumer for username" + username);
+ }
+ } catch (APIManagementException e) {
+ throw new APIManagerException("Failed to create application [name:" + applicationName + " , username:"
+ + username + ", " + "groupId:" + groupId, e);
+ }
+ }
+
+ private void addSubscription(APIConsumer apiConsumer, APIIdentifier apiId, int applicationId, String username)
+ throws APIManagerException {
+ try {
+ if (apiConsumer != null) {
+ APIIdentifier apiIdentifier = new APIIdentifier(apiId.getProviderName(), apiId.getApiName(),
+ apiId.getVersion());
+ apiIdentifier.setTier(ApiApplicationConstants.DEFAULT_TIER);
+ apiConsumer.addSubscription(apiIdentifier, username, applicationId);
+ if (log.isDebugEnabled()) {
+ log.debug("Successfully created subscription for API : " + apiId + " from application : " +
+ applicationId);
+ }
+ } else {
+ throw new APIManagerException("API provider configured for the given API configuration is null. " +
+ "Thus, the API is not published");
+ }
+ } catch (APIManagementException e) {
+ throw new APIManagerException("Failed to create subscription for api name : " + apiId.getApiName(), e);
+ }
+ }
+
+
+ private void addSubscriber(String subscriberName, String subscriberEmail, String groupId, int tenantId)
+ throws APIManagerException {
+ if (log.isDebugEnabled()) {
+ log.debug("Creating subscriber with name " + subscriberName);
+ }
+ try {
+ APIConsumer consumer = APIManagerFactory.getInstance().getAPIConsumer(subscriberName);
+ if (consumer != null) {
+ Subscriber subscriber = new Subscriber(subscriberName);
+ subscriber.setSubscribedDate(new Date());
+ subscriber.setEmail(subscriberEmail);
+ subscriber.setTenantId(tenantId);
+ consumer.addSubscriber(subscriber, groupId);
+ if (log.isDebugEnabled()) {
+ log.debug("Successfully created subscriber with name : " + subscriberName + " with groupID : " +
+ groupId);
+ }
+ } else {
+ throw new APIManagerException("API provider configured for the given API configuration is null. " +
+ "Thus, the API is not published");
+ }
+ } catch (APIManagementException e) {
+ throw new APIManagerException("API provider configured for the given API configuration is null. " +
+ "Thus, the API is not published", e);
+ }
+ }
+
+ /**
+ * This method registers an api application and then subscribe the application to the api.
+ *
+ * @param apiApplicationName name of the application.
+ * @param tags are used subscribe the apis with the tag.
+ * @param username subscription is created for the user.
+ * @throws APIManagerException
+ */
+ private int createApplicationAndSubscribeToAPIs(String apiApplicationName, String tags[], String username)
+ throws APIManagerException {
+ try {
+ APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
+ String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
+ int applicationId = createApplication(apiConsumer, apiApplicationName, username, groupId);
+ Subscriber subscriber = apiConsumer.getSubscriber(username);
+ Set userVisibleAPIs = null;
+ for (String tag : tags) {
+ Set tagAPIs = apiConsumer.getAPIsWithTag(tag);
+ if (userVisibleAPIs == null) {
+ userVisibleAPIs = tagAPIs;
+ } else {
+ userVisibleAPIs.addAll(tagAPIs);
+ }
+ }
+ if (userVisibleAPIs != null) {
+ Set subscribedAPIs = apiConsumer.getSubscribedAPIs(subscriber, apiApplicationName,
+ groupId);
+ for (API userVisbleAPI : userVisibleAPIs) {
+ APIIdentifier apiIdentifier = userVisbleAPI.getId();
+ boolean isSubscribed = false;
+ if (subscribedAPIs != null) {
+ for (SubscribedAPI subscribedAPI : subscribedAPIs) {
+ if (subscribedAPI.getApiId().equals(apiIdentifier)) {
+ isSubscribed = true;
+ }
+ }
+ }
+ if (!isSubscribed) {
+ addSubscription(apiConsumer, apiIdentifier, applicationId, username);
+ }
+ }
+ }
+ return applicationId;
+ } catch (APIManagementException e) {
+ throw new APIManagerException("Failed to fetch device apis information for the user " + username, e);
+ }
+ }
+
+ /**
+ * This method registers an api application and then subscribe the application to the api.
+ *
+ * @param username subscription is created for the user.
+ * @throws APIManagerException
+ */
+ private int createApplicationAndSubscribeToAllAPIs(String apiApplicationName, String username)
+ throws APIManagerException {
+ try {
+ APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
+ String groupId = getLoggedInUserGroupId(username, APIManagerUtil.getTenantDomain());
+ int applicationId = createApplication(apiConsumer, apiApplicationName, username, groupId);
+ String tenantDomain = MultitenantUtils.getTenantDomain(username);
+ Set userVisibleAPIs = apiConsumer.getAllPublishedAPIs(tenantDomain);
+ Subscriber subscriber = apiConsumer.getSubscriber(username);
+ Set subscribedAPIs = apiConsumer.getSubscribedAPIs(subscriber);
+ for (API visibleApi : userVisibleAPIs) {
+ APIIdentifier apiIdentifier = visibleApi.getId();
+ boolean isSubscribed = false;
+ for (SubscribedAPI subscribedAPI : subscribedAPIs) {
+ if (subscribedAPI.getApiId().equals(apiIdentifier)) {
+ isSubscribed = true;
+ }
+ }
+ if (!isSubscribed) {
+ addSubscription(apiConsumer, apiIdentifier, applicationId, username);
+ }
+ }
+ return applicationId;
+ } catch (APIManagementException e) {
+ throw new APIManagerException("Failed to fetch device apis information for the user " + username, e);
+ }
+ }
+
+ private String getLoggedInUserGroupId(String username, String tenantDomain) throws APIManagerException {
+ JSONObject loginInfoJsonObj = new JSONObject();
+ try {
+ APIConsumer apiConsumer = APIManagerFactory.getInstance().getAPIConsumer(username);
+ loginInfoJsonObj.put("user", username);
+ if (tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
+ loginInfoJsonObj.put("isSuperTenant", true);
+ } else {
+ loginInfoJsonObj.put("isSuperTenant", false);
+ }
+ String loginInfoString = loginInfoJsonObj.toString();
+ return apiConsumer.getGroupIds(loginInfoString);
+ } catch (APIManagementException e) {
+ throw new APIManagerException("Unable to get groupIds of user " + username, e);
+ }
+ }
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/constants/ApiApplicationConstants.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/constants/ApiApplicationConstants.java
new file mode 100644
index 0000000000..821256a2af
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/constants/ApiApplicationConstants.java
@@ -0,0 +1,31 @@
+/*
+ * 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.apimgt.application.extension.constants;
+
+public class ApiApplicationConstants {
+ public static final String DEFAULT_TOKEN_TYPE = "PRODUCTION";
+ public static final String DEFAULT_TIER = "Unlimited";
+ public static final String ALLOWED_DOMAINS = "ALL";
+ public static final String OAUTH_CLIENT_ID = "client_id";
+ public static final String OAUTH_CLIENT_SECRET = "client_secret";
+ public static final String DEFAULT_VALIDITY_PERIOD = "3600";
+ public static final String JSONSTRING_USERNAME_TAG = "username";
+ public static final String JSONSTRING_KEY_TYPE_TAG = "key_type";
+ public static final String JSONSTRING_VALIDITY_PERIOD_TAG = "validityPeriod";
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/dto/ApiApplicationKey.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/dto/ApiApplicationKey.java
new file mode 100644
index 0000000000..58e3b713e1
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/dto/ApiApplicationKey.java
@@ -0,0 +1,53 @@
+/*
+ * 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.apimgt.application.extension.dto;
+
+import org.json.simple.JSONObject;
+import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants;
+
+/**
+ * This holds api application consumer key and secret.
+ */
+public class ApiApplicationKey {
+ private String consumerKey;
+ private String consumerSecret;
+
+ public String getConsumerKey() {
+ return this.consumerKey;
+ }
+
+ public void setConsumerKey(String consumerKey) {
+ this.consumerKey = consumerKey;
+ }
+
+ public String getConsumerSecret() {
+ return this.consumerSecret;
+ }
+
+ public void setConsumerSecret(String consumerSecret) {
+ this.consumerSecret = consumerSecret;
+ }
+
+ public String toString() {
+ JSONObject obj = new JSONObject();
+ obj.put(ApiApplicationConstants.OAUTH_CLIENT_ID, this.getConsumerKey());
+ obj.put(ApiApplicationConstants.OAUTH_CLIENT_SECRET, this.getConsumerSecret());
+ return obj.toString();
+ }
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/exception/APIManagerException.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/exception/APIManagerException.java
new file mode 100644
index 0000000000..b77bb584f4
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/exception/APIManagerException.java
@@ -0,0 +1,60 @@
+/*
+ * 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.apimgt.application.extension.exception;
+
+/**
+ * Handles the exceptions related to API management.
+ */
+public class APIManagerException extends Exception {
+
+ private static final long serialVersionUID = -8933142342423122660L;
+ private String errorMessage;
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public APIManagerException(String msg, Exception nestedEx) {
+ super(msg, nestedEx);
+ setErrorMessage(msg);
+ }
+
+ public APIManagerException(String message, Throwable cause) {
+ super(message, cause);
+ setErrorMessage(message);
+ }
+
+ public APIManagerException(String msg) {
+ super(msg);
+ setErrorMessage(msg);
+ }
+
+ public APIManagerException() {
+ super();
+ }
+
+ public APIManagerException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java
new file mode 100644
index 0000000000..6f360ae649
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java
@@ -0,0 +1,69 @@
+/*
+ * 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.apimgt.application.extension.internal;
+
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.user.core.service.RealmService;
+import org.wso2.carbon.user.core.tenant.TenantManager;
+
+public class APIApplicationManagerExtensionDataHolder {
+ private static APIApplicationManagerExtensionDataHolder thisInstance = new APIApplicationManagerExtensionDataHolder();
+ private APIManagementProviderService apiManagementProviderService;
+ private RealmService realmService;
+ private TenantManager tenantManager;
+
+ private APIApplicationManagerExtensionDataHolder() {
+ }
+
+
+ public static APIApplicationManagerExtensionDataHolder getInstance() {
+ return thisInstance;
+ }
+
+ public APIManagementProviderService getAPIManagementProviderService() {
+ return apiManagementProviderService;
+ }
+
+ public void setAPIManagementProviderService(
+ APIManagementProviderService apiManagementProviderService) {
+ this.apiManagementProviderService = apiManagementProviderService;
+ }
+
+ public RealmService getRealmService() {
+ if (realmService == null) {
+ throw new IllegalStateException("Realm service is not initialized properly");
+ }
+ return realmService;
+ }
+
+ public void setRealmService(RealmService realmService) {
+ this.realmService = realmService;
+ this.setTenantManager(realmService);
+ }
+
+ private void setTenantManager(RealmService realmService) {
+ if (realmService == null) {
+ throw new IllegalStateException("Realm service is not initialized properly");
+ }
+ this.tenantManager = realmService.getTenantManager();
+ }
+
+ public TenantManager getTenantManager() {
+ return tenantManager;
+ }
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java
new file mode 100644
index 0000000000..557d47aa11
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java
@@ -0,0 +1,79 @@
+/*
+ * 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.apimgt.application.extension.internal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;;
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService;
+import org.wso2.carbon.apimgt.application.extension.APIManagementProviderServiceImpl;
+import org.wso2.carbon.user.core.service.RealmService;
+
+/**
+ * @scr.component name="org.wso2.carbon.apimgt.application.extension.internal.APIApplicationManagerExtensionServiceComponent"
+ * @scr.reference name="realm.service"
+ * immediate="true"
+ * interface="org.wso2.carbon.user.core.service.RealmService"
+ * cardinality="1..1"
+ * policy="dynamic"
+ * bind="setRealmService"
+ * unbind="unsetRealmService"
+ */
+public class APIApplicationManagerExtensionServiceComponent {
+
+ private static Log log = LogFactory.getLog(APIApplicationManagerExtensionServiceComponent.class);
+
+ protected void activate(ComponentContext componentContext) {
+ if (log.isDebugEnabled()) {
+ log.debug("Initializing device extension bundle");
+ }
+ APIManagementProviderService apiManagementProviderService = new APIManagementProviderServiceImpl();
+ APIApplicationManagerExtensionDataHolder.getInstance().setAPIManagementProviderService(apiManagementProviderService);
+ BundleContext bundleContext = componentContext.getBundleContext();
+ bundleContext.registerService(APIManagementProviderService.class.getName(), apiManagementProviderService, null);
+ }
+
+ protected void deactivate(ComponentContext componentContext) {
+ //do nothing
+ }
+
+ /**
+ * Sets Realm Service.
+ *
+ * @param realmService An instance of RealmService
+ */
+ protected void setRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Setting Realm Service");
+ }
+ APIApplicationManagerExtensionDataHolder.getInstance().setRealmService(realmService);
+ }
+
+ /**
+ * Unsets Realm Service.
+ *
+ * @param realmService An instance of RealmService
+ */
+ protected void unsetRealmService(RealmService realmService) {
+ if (log.isDebugEnabled()) {
+ log.debug("Unsetting Realm Service");
+ }
+ APIApplicationManagerExtensionDataHolder.getInstance().setRealmService(null);
+ }
+}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/util/APIManagerUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/util/APIManagerUtil.java
new file mode 100644
index 0000000000..96dba4cfb4
--- /dev/null
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/util/APIManagerUtil.java
@@ -0,0 +1,55 @@
+/*
+ * 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.apimgt.application.extension.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException;
+import org.wso2.carbon.apimgt.application.extension.internal.APIApplicationManagerExtensionDataHolder;
+import org.wso2.carbon.base.MultitenantConstants;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.user.api.TenantManager;
+import org.wso2.carbon.user.api.UserStoreException;
+
+public final class APIManagerUtil {
+
+ private static final Log log = LogFactory.getLog(APIManagerUtil.class);
+
+ /**
+ * returns the tenant Id of the specific tenant Domain
+ */
+ public static int getTenantId(String tenantDomain) throws APIManagerException {
+ try {
+ if (tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) {
+ return MultitenantConstants.SUPER_TENANT_ID;
+ }
+ TenantManager tenantManager = APIApplicationManagerExtensionDataHolder.getInstance().getTenantManager();
+ int tenantId = tenantManager.getTenantId(tenantDomain);
+ if (tenantId == -1) {
+ throw new APIManagerException("invalid tenant Domain :" + tenantDomain);
+ }
+ return tenantId;
+ } catch (UserStoreException e) {
+ throw new APIManagerException("invalid tenant Domain :" + tenantDomain);
+ }
+ }
+
+ public static String getTenantDomain() {
+ return PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
+ }
+}
diff --git a/components/apimgt-extensions/pom.xml b/components/apimgt-extensions/pom.xml
index 2ff22c9086..c17a81051c 100644
--- a/components/apimgt-extensions/pom.xml
+++ b/components/apimgt-extensions/pom.xml
@@ -1,21 +1,21 @@
+ ~ 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.
+ -->
@@ -27,7 +27,6 @@
4.0.0
- org.wso2.carbon.devicemgt
apimgt-extensions
1.1.0-SNAPSHOT
pom
@@ -36,6 +35,9 @@
org.wso2.carbon.apimgt.webapp.publisher
+ org.wso2.carbon.apimgt.application.extension
+ org.wso2.carbon.apimgt.application.extension.api
+ org.wso2.carbon.apimgt.annotations
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/Feature.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/Feature.java
index a2dd906220..375b8d4562 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/Feature.java
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/Feature.java
@@ -1,22 +1,23 @@
/*
- * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ * 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
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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
+ * 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.common;
+import javax.xml.bind.annotation.XmlElement;
import java.io.Serializable;
import java.util.List;
@@ -27,8 +28,11 @@ public class Feature implements Serializable {
private String name;
private String description;
private String deviceType;
+ private String method;
+ private String type;
private List metadataEntries;
+ @XmlElement
public int getId() {
return id;
}
@@ -37,6 +41,7 @@ public class Feature implements Serializable {
this.id = id;
}
+ @XmlElement
public String getCode() {
return code;
}
@@ -45,6 +50,7 @@ public class Feature implements Serializable {
this.code = code;
}
+ @XmlElement
public String getName() {
return name;
}
@@ -61,6 +67,7 @@ public class Feature implements Serializable {
this.metadataEntries = metadataEntries;
}
+ @XmlElement
public String getDeviceType() {
return deviceType;
}
@@ -69,6 +76,7 @@ public class Feature implements Serializable {
this.deviceType = deviceType;
}
+ @XmlElement
public String getDescription() {
return description;
}
@@ -77,6 +85,24 @@ public class Feature implements Serializable {
this.description = description;
}
+ @XmlElement
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ @XmlElement
+ public String getMethod() {
+ return method;
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
public static class MetadataEntry implements Serializable {
private int id;
@@ -98,5 +124,4 @@ public class Feature implements Serializable {
this.value = value;
}
}
-
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/pom.xml
index 3a89167525..2eb681d946 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/pom.xml
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/pom.xml
@@ -1,4 +1,22 @@
+
+
@@ -40,6 +58,38 @@
org.wso2.carbon
org.wso2.carbon.utils
+
+ org.wso2.orbit.org.scannotation
+ scannotation
+
+
+ org.eclipse.osgi
+ org.eclipse.osgi
+
+
+ org.eclipse.osgi
+ org.eclipse.osgi.services
+
+
+ org.wso2.tomcat
+ tomcat
+
+
+ org.wso2.tomcat
+ tomcat-servlet-api
+
+
+ javax.ws.rs
+ jsr311-api
+
+
+ org.apache.axis2.wso2
+ axis2
+
+
+ commons-lang.wso2
+ commons-lang
+
@@ -59,7 +109,7 @@
org.wso2.carbon.governance.api.*,
- javax.xml.namespace,
+ javax.xml.namespace;resolution:=optional,
org.wso2.carbon.context,
org.wso2.carbon.device.mgt.common,
org.wso2.carbon.device.mgt.common.license.mgt,
@@ -69,7 +119,14 @@
org.wso2.carbon.registry.core.session,
javax.xml.bind,
org.wso2.carbon.utils,
- org.apache.commons.logging
+ org.apache.commons.logging,
+ org.apache.catalina,
+ org.apache.catalina.core,
+ javax.servlet;resolution:=optional,
+ javax.xml.*;resolution:=optional,
+ org.apache.commons.lang,
+ javax.ws.rs;resolution:=optional,
+ org.scannotation
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/GenericFeatureManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/GenericFeatureManager.java
new file mode 100644
index 0000000000..2da3394542
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/GenericFeatureManager.java
@@ -0,0 +1,76 @@
+/*
+ * 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.extensions.feature.mgt;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.device.mgt.common.DeviceManagementException;
+import org.wso2.carbon.device.mgt.common.Feature;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This stores the features for device types that are mentioned through the annotations.
+ */
+public class GenericFeatureManager {
+
+ private static final Log log = LogFactory.getLog(GenericFeatureManager.class);
+ private static Map> featureSet = new HashMap<>();
+ private static GenericFeatureManager instance = new GenericFeatureManager();
+
+ private GenericFeatureManager() {
+ }
+
+ public static GenericFeatureManager getInstance() {
+ return instance;
+ }
+
+ /**
+ * @param deviceTypeFeatures feature list for each device type.
+ */
+ public void addFeatures(Map> deviceTypeFeatures) {
+ this.featureSet.putAll(deviceTypeFeatures);
+ }
+
+ /**
+ * @param deviceType
+ * @param featureName
+ * @return the extracted feature for the which matches the feature name and device type.
+ */
+ public Feature getFeature(String deviceType, String featureName) {
+ Feature extractedFeature = null;
+ List deviceFeatureList = featureSet.get(deviceType);
+ for (Feature feature : deviceFeatureList) {
+ if (feature.getName().equalsIgnoreCase(featureName)) {
+ extractedFeature = feature;
+ }
+ }
+ return extractedFeature;
+ }
+
+ /**
+ * @param deviceType returns the features for the device type.
+ * @return
+ */
+ public List getFeatures(String deviceType) {
+ return featureSet.get(deviceType);
+ }
+
+}
\ No newline at end of file
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/annotations/DeviceType.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/annotations/DeviceType.java
new file mode 100644
index 0000000000..7c7d635889
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/annotations/DeviceType.java
@@ -0,0 +1,29 @@
+/*
+ * 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.extensions.feature.mgt.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DeviceType {
+ String value();
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/annotations/Feature.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/annotations/Feature.java
new file mode 100644
index 0000000000..da0040f982
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/annotations/Feature.java
@@ -0,0 +1,36 @@
+/*
+ * 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.extensions.feature.mgt.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Feature {
+
+ String code();
+
+ String name();
+
+ String description();
+
+ String type();
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/lifecycle/listener/FeatureManagementLifecycleListener.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/lifecycle/listener/FeatureManagementLifecycleListener.java
new file mode 100644
index 0000000000..57ae592ee6
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/lifecycle/listener/FeatureManagementLifecycleListener.java
@@ -0,0 +1,71 @@
+/*
+ * 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.extensions.feature.mgt.lifecycle.listener;
+
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.core.StandardContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.device.mgt.common.Feature;
+import org.wso2.carbon.device.mgt.extensions.feature.mgt.GenericFeatureManager;
+import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
+import org.wso2.carbon.device.mgt.extensions.feature.mgt.util.AnnotationUtil;
+
+import javax.servlet.ServletContext;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@SuppressWarnings("unused")
+public class FeatureManagementLifecycleListener implements LifecycleListener {
+
+ private static final String API_CONFIG_DEFAULT_VERSION = "1.0.0";
+
+ private static final String PARAM_MANAGED_API_ENABLED = "managed-api-enabled";
+
+ private static final Log log = LogFactory.getLog(FeatureManagementLifecycleListener.class);
+ private static final String UNLIMITED = "Unlimited";
+
+ @Override
+ public void lifecycleEvent(LifecycleEvent lifecycleEvent) {
+ if (Lifecycle.AFTER_START_EVENT.equals(lifecycleEvent.getType())) {
+ StandardContext context = (StandardContext) lifecycleEvent.getLifecycle();
+ ServletContext servletContext = context.getServletContext();
+ String param = servletContext.getInitParameter(PARAM_MANAGED_API_ENABLED);
+ boolean isManagedApi = (param != null && !param.isEmpty()) && Boolean.parseBoolean(param);
+ if (isManagedApi) {
+ try {
+ AnnotationUtil annotationUtil = new AnnotationUtil(context);
+ Set annotatedAPIClasses = annotationUtil.scanStandardContext(DeviceType.class.getName());
+ Map> features = annotationUtil.extractFeatures(annotatedAPIClasses);
+ if (features != null && !features.isEmpty()) {
+ GenericFeatureManager.getInstance().addFeatures(features);
+ }
+ } catch (IOException e) {
+ log.error("Error enconterd while discovering annotated classes.", e);
+ } catch (ClassNotFoundException e) {
+ log.error("Error while scanning class for annotations.", e);
+ }
+ }
+ }
+ }
+
+}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/util/AnnotationUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/util/AnnotationUtil.java
new file mode 100644
index 0000000000..621de44372
--- /dev/null
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/feature/mgt/util/AnnotationUtil.java
@@ -0,0 +1,221 @@
+/*
+ * 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.extensions.feature.mgt.util;
+
+import org.apache.catalina.core.StandardContext;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.scannotation.AnnotationDB;
+import org.scannotation.WarUrlFinder;
+import org.wso2.carbon.device.mgt.common.Feature;
+import org.wso2.carbon.device.mgt.extensions.feature.mgt.annotations.DeviceType;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.OPTIONS;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This has the utility function to extract feature information.
+ */
+public class AnnotationUtil {
+
+ private static final Log log = LogFactory.getLog(AnnotationUtil.class);
+
+ private static final String PACKAGE_ORG_APACHE = "org.apache";
+ private static final String PACKAGE_ORG_CODEHAUS = "org.codehaus";
+ private static final String PACKAGE_ORG_SPRINGFRAMEWORK = "org.springframework";
+ public static final String STRING_ARR = "string_arr";
+ public static final String STRING = "string";
+ private Class featureClazz;
+ private ClassLoader classLoader;
+ private ServletContext servletContext;
+
+
+ public AnnotationUtil(final StandardContext context) {
+ servletContext = context.getServletContext();
+ classLoader = servletContext.getClassLoader();
+ }
+
+ /**
+ * Scan the context for classes with annotations
+ */
+ public Set scanStandardContext(String className) throws IOException {
+ AnnotationDB db = new AnnotationDB();
+ db.addIgnoredPackages(PACKAGE_ORG_APACHE);
+ db.addIgnoredPackages(PACKAGE_ORG_CODEHAUS);
+ db.addIgnoredPackages(PACKAGE_ORG_SPRINGFRAMEWORK);
+ URL[] libPath = WarUrlFinder.findWebInfLibClasspaths(servletContext);
+ URL classPath = WarUrlFinder.findWebInfClassesPath(servletContext);
+ URL[] urls = (URL[]) ArrayUtils.add(libPath, libPath.length, classPath);
+ db.scanArchives(urls);
+
+ //Returns a list of classes with given Annotation
+ return db.getAnnotationIndex().get(className);
+ }
+
+ /**
+ * Method identifies the URL templates and context by reading the annotations of a class
+ */
+ public Map> extractFeatures(Set entityClasses) throws ClassNotFoundException {
+ Map> features = null;
+ if (entityClasses != null && !entityClasses.isEmpty()) {
+ features = new HashMap<>();
+ for (final String className : entityClasses) {
+ final Map> featureMap =
+ AccessController.doPrivileged(new PrivilegedAction