diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java index 4d8835463e..89444ecc9e 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java @@ -90,6 +90,15 @@ public class APIPublisherStartupHandler implements ServerStartupObserver { } catch (APIManagerPublisherException e) { log.error("failed to update scope role mapping.", e); } + + // execute after api publishing + for (PostApiPublishingObsever observer : APIPublisherDataHolder.getInstance().getPostApiPublishingObseverList()) { + if (log.isDebugEnabled()) { + log.debug("Executing " + observer.getClass().getName()); + } + observer.execute(); + } + log.info("Finish executing PostApiPublishingObsevers"); } }); t.start(); diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/PostApiPublishingObsever.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/PostApiPublishingObsever.java new file mode 100644 index 0000000000..392e780300 --- /dev/null +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/PostApiPublishingObsever.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.apimgt.webapp.publisher; + +public interface PostApiPublishingObsever { + void execute(); + +} diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java index 4f8e5599bf..d00f50e35f 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherDataHolder.java @@ -22,6 +22,7 @@ import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServi import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIConfig; import io.entgra.device.mgt.core.apimgt.webapp.publisher.APIPublisherService; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; +import io.entgra.device.mgt.core.apimgt.webapp.publisher.PostApiPublishingObsever; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.registry.core.service.RegistryService; @@ -32,9 +33,11 @@ import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.user.core.tenant.TenantManager; import org.wso2.carbon.utils.ConfigurationContextService; -import java.util.HashMap; import java.util.Map; import java.util.Stack; +import java.util.List; +import java.util.ArrayList; + public class APIPublisherDataHolder { @@ -52,6 +55,7 @@ public class APIPublisherDataHolder { private static APIPublisherDataHolder thisInstance = new APIPublisherDataHolder(); + private List postApiPublishingObseverList = new ArrayList<>(); private APIPublisherDataHolder() { } @@ -179,4 +183,16 @@ public class APIPublisherDataHolder { public void setMetadataManagementService(MetadataManagementService metadataManagementService) { this.metadataManagementService = metadataManagementService; } + + public List getPostApiPublishingObseverList() { + return postApiPublishingObseverList; + } + + public void addPostApiPublishingObseverList(PostApiPublishingObsever postApiPublishingObseverList) { + this.postApiPublishingObseverList.add(postApiPublishingObseverList); + } + + public void removePostApiPublishingObseverList(PostApiPublishingObsever postApiPublishingObsever) { + this.postApiPublishingObseverList.remove(postApiPublishingObsever); + } } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java index a3814ddbf1..a6b2773d47 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/internal/APIPublisherServiceComponent.java @@ -20,6 +20,7 @@ package io.entgra.device.mgt.core.apimgt.webapp.publisher.internal; import io.entgra.device.mgt.core.apimgt.extension.rest.api.APIApplicationServices; import io.entgra.device.mgt.core.apimgt.extension.rest.api.PublisherRESTAPIServices; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; +import io.entgra.device.mgt.core.apimgt.webapp.publisher.PostApiPublishingObsever; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; @@ -179,4 +180,24 @@ public class APIPublisherServiceComponent { APIPublisherDataHolder.getInstance().setMetadataManagementService(null); } + @Reference( + name = "postApiPublishingObsever", + service = io.entgra.device.mgt.core.apimgt.webapp.publisher.PostApiPublishingObsever.class, + cardinality = ReferenceCardinality.MULTIPLE, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetPostApiPublishingObsever") + protected void setPostApiPublishingObsever(PostApiPublishingObsever postApiPublishingObsever) { + if (log.isDebugEnabled()) { + log.debug("Setting PostApiPublishingObsever"); + } + APIPublisherDataHolder.getInstance().addPostApiPublishingObseverList(postApiPublishingObsever); + } + + protected void unsetPostApiPublishingObsever(PostApiPublishingObsever postApiPublishingObsever) { + if (log.isDebugEnabled()) { + log.debug("Unsetting PostApiPublishingObsever"); + } + APIPublisherDataHolder.getInstance().removePostApiPublishingObseverList(postApiPublishingObsever); + } + } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java index 52f10eb16b..8ef96ef934 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/api/DeviceManagementService.java @@ -2652,7 +2652,12 @@ public interface DeviceManagementService { name = "appName", value = "App name to be searched") @QueryParam("appName") - String appName); + String appName, + @ApiParam( + name = "packageName", + value = "App package name to be searched") + @QueryParam("packageName") + String packageName); @GET @Path("/application/{packageName}/versions") diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java index 96e3919929..43da49fc7e 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -42,6 +42,7 @@ import io.entgra.device.mgt.core.application.mgt.common.services.ApplicationMana import io.entgra.device.mgt.core.application.mgt.common.services.SubscriptionManager; import io.entgra.device.mgt.core.application.mgt.core.util.HelperUtil; import io.entgra.device.mgt.core.device.mgt.api.jaxrs.service.impl.util.DisenrollRequest; +import io.entgra.device.mgt.core.device.mgt.api.jaxrs.util.DeviceMgtUtil; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -1613,11 +1614,13 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { @QueryParam("offset") int offset, @DefaultValue("10") @QueryParam("limit") int limit, - @QueryParam("appName") String appName) { + @QueryParam("appName") String appName, + @QueryParam("packageName") String packageName) { PaginationRequest request = new PaginationRequest(offset, limit); ApplicationList applicationList = new ApplicationList(); request.setDeviceType(deviceType); - request.setFilter(appName); + request.setFilter(DeviceMgtUtil.buildAppSearchFilter(appName, packageName)); + try { PaginationResult paginationResult = DeviceMgtAPIUtils .getDeviceManagementService() diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/util/DeviceMgtUtil.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/util/DeviceMgtUtil.java index c126c4704a..d6955e4f39 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/util/DeviceMgtUtil.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.api/src/main/java/io/entgra/device/mgt/core/device/mgt/api/jaxrs/util/DeviceMgtUtil.java @@ -18,13 +18,15 @@ package io.entgra.device.mgt.core.device.mgt.api.jaxrs.util; +import io.entgra.device.mgt.core.device.mgt.core.config.permission.Scope; import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ErrorListItem; import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ErrorResponse; import io.entgra.device.mgt.core.device.mgt.api.jaxrs.beans.ProfileFeature; import io.entgra.device.mgt.core.device.mgt.api.jaxrs.exception.BadRequestException; import io.entgra.device.mgt.core.device.mgt.common.policy.mgt.Profile; -import io.entgra.device.mgt.core.device.mgt.core.config.permission.Scope; +import io.entgra.device.mgt.core.device.mgt.common.app.mgt.ApplicationFilter; +import com.google.gson.Gson; import javax.validation.ConstraintViolation; import java.util.ArrayList; import java.util.List; @@ -141,4 +143,12 @@ public class DeviceMgtUtil { errorResponse.setErrorItems(errorListItems); return errorResponse; } + + public static String buildAppSearchFilter(String appName, String packageName) { + //Create search filter as a Json string to attach into the filter in PaginationRequest + ApplicationFilter applicationFilter = new ApplicationFilter(); + applicationFilter.setAppName(appName); + applicationFilter.setPackageName(packageName); + return new Gson().toJson(applicationFilter); + } } \ No newline at end of file diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/app/mgt/ApplicationFilter.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/app/mgt/ApplicationFilter.java new file mode 100644 index 0000000000..f9f7c3d757 --- /dev/null +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.common/src/main/java/io/entgra/device/mgt/core/device/mgt/common/app/mgt/ApplicationFilter.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018 - 2024, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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 io.entgra.device.mgt.core.device.mgt.common.app.mgt; + +public class ApplicationFilter { + public static final class FilterProperties { + public static final String REGEX_WHITESPACE = ".*\\s.*"; + public static final String REGEX_WHITESPACE_REPLACER = "\\s+"; + public static final String URL_ENCODE_SPACE = "%20"; + } + + private String appName; + private String packageName; + + public String getAppName() { + return appName; + } + + public void setAppName(String appName) { + this.appName = appName; + if (this.appName != null && !this.appName.isEmpty() && + //Check if the filter contains spaces and replace URL encode them + this.appName.matches(FilterProperties.REGEX_WHITESPACE)) { + this.appName = this.appName + .replaceAll(FilterProperties.REGEX_WHITESPACE_REPLACER, + FilterProperties.URL_ENCODE_SPACE); + } + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } +} diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/common/Constants.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/common/Constants.java index 71eaf20a5f..68111a5159 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/common/Constants.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/common/Constants.java @@ -21,6 +21,7 @@ package io.entgra.device.mgt.core.device.mgt.core.common; public class Constants { public static final String SCHEME_SEPARATOR = "://"; public static final String COLON = ":"; + public static final String QUERY_WILDCARD = "%"; public static final String URI_QUERY_SEPARATOR = "?"; public static final String URI_SEPARATOR = "/"; public static final String BASIC_AUTH_HEADER_PREFIX = "Basic "; diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/ApplicationDAOImpl.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/ApplicationDAOImpl.java index c701399324..3691b10ee3 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/ApplicationDAOImpl.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/dao/impl/ApplicationDAOImpl.java @@ -17,14 +17,18 @@ */ package io.entgra.device.mgt.core.device.mgt.core.dao.impl; +import com.google.gson.Gson; +import io.entgra.device.mgt.core.device.mgt.common.app.mgt.ApplicationFilter; +import io.entgra.device.mgt.core.device.mgt.core.common.Constants; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import io.entgra.device.mgt.core.device.mgt.common.PaginationRequest; import io.entgra.device.mgt.core.device.mgt.common.app.mgt.Application; import io.entgra.device.mgt.core.device.mgt.core.dao.ApplicationDAO; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOException; import io.entgra.device.mgt.core.device.mgt.core.dao.DeviceManagementDAOFactory; import io.entgra.device.mgt.core.device.mgt.core.dao.util.DeviceManagementDAOUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; + import java.io.ByteArrayInputStream; import java.io.IOException; @@ -294,12 +298,27 @@ public class ApplicationDAOImpl implements ApplicationDAO { "PLATFORM = ? AND TENANT_ID = ?) "; try { - String filter = request.getFilter(); - if (filter != null) { + ApplicationFilter applicationFilter = new Gson().fromJson(request.getFilter(), ApplicationFilter.class); + boolean isAppNameFilterProvided = false; + if (null != applicationFilter.getAppName()) { sql = sql + "AND NAME LIKE ? "; + applicationFilter.setAppName(Constants.QUERY_WILDCARD.concat(applicationFilter.getAppName()) + .concat(Constants.QUERY_WILDCARD)); + isAppNameFilterProvided = true; } + + boolean isPackageFilterProvided = false; + if (null != applicationFilter.getPackageName()) { + sql = sql + "AND APP_IDENTIFIER LIKE ? "; + applicationFilter.setPackageName(Constants.QUERY_WILDCARD.concat(applicationFilter.getPackageName()) + .concat(Constants.QUERY_WILDCARD)); + isPackageFilterProvided = true; + } + + boolean isLimitPresent = false; if (request != null && request.getRowCount() != -1) { sql = sql + "LIMIT ? OFFSET ?"; + isLimitPresent = true; } Connection conn = this.getConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -308,10 +327,13 @@ public class ApplicationDAOImpl implements ApplicationDAO { stmt.setInt(paramIdx++, tenantId); stmt.setString(paramIdx++, request.getDeviceType()); stmt.setInt(paramIdx++, tenantId); - if (filter != null){ - stmt.setString(paramIdx++, filter); + if (isAppNameFilterProvided){ + stmt.setString(paramIdx++, applicationFilter.getAppName()); + } + if (isPackageFilterProvided){ + stmt.setString(paramIdx++, applicationFilter.getPackageName()); } - if (request != null && request.getRowCount() != -1) { + if (isLimitPresent) { stmt.setInt(paramIdx++, request.getRowCount()); stmt.setInt(paramIdx, request.getStartIndex()); } diff --git a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index ce963d1437..b0de3dc590 100644 --- a/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/io.entgra.device.mgt.core.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -463,6 +463,8 @@ CREATE TABLE IF NOT EXISTS DM_APPLICATION ( )ENGINE = InnoDB; CREATE INDEX IDX_DM_APPLICATION ON DM_APPLICATION(DEVICE_ID, ENROLMENT_ID, TENANT_ID); +CREATE INDEX DM_APPLICATION_NAME ON DM_APPLICATION(NAME); +CREATE INDEX DM_APPLICATION_NAME_PLATFORM_TID ON DM_APPLICATION(NAME, PLATFORM, TENANT_ID); -- END OF POLICY RELATED TABLES --