diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/Base64File.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/Base64File.java new file mode 100644 index 00000000000..51e9add3722 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/Base64File.java @@ -0,0 +1,23 @@ +package io.entgra.application.mgt.common; + +public class Base64File { + + private String name; + private String base64String; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getBase64String() { + return base64String; + } + + public void setBase64String(String base64String) { + this.base64String = base64String; + } +} diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/FileDataHolder.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/FileDataHolder.java new file mode 100644 index 00000000000..4bb36c6c640 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/FileDataHolder.java @@ -0,0 +1,33 @@ +package io.entgra.application.mgt.common; + +import java.io.InputStream; + +public class FileDataHolder { + + private String name; + private InputStream file; + + public FileDataHolder(String name, InputStream file) { + this.name = name; + this.file = file; + } + public FileDataHolder() { + + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public InputStream getFile() { + return file; + } + + public void setFile(InputStream file) { + this.file = file; + } +} diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/IdentityServer.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/IdentityServer.java new file mode 100644 index 00000000000..4bc0ddee020 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/IdentityServer.java @@ -0,0 +1,77 @@ +package io.entgra.application.mgt.common; + + +public class IdentityServer { + private int id; + private String name; + private String description; + private String url; + private String spAppsUri; + private String spAppsApi; + private String userName; + private String password; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getSpAppsUri() { + return spAppsUri; + } + + public void setSpAppsURI(String spAppsUri) { + this.spAppsUri = spAppsUri; + } + + public String getSpAppsApi() { + return spAppsApi; + } + + public void setSpAppsApi(String spAppsApi) { + this.spAppsApi = spAppsApi; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } +} diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/IdentityServerList.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/IdentityServerList.java new file mode 100644 index 00000000000..5f1deaacf18 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/IdentityServerList.java @@ -0,0 +1,15 @@ +package io.entgra.application.mgt.common; + +import java.util.List; + +public class IdentityServerList { + private List identityServers; + + public List getIdentityServers() { + return identityServers; + } + + public void setIdentityServers(List identityServers) { + this.identityServers = identityServers; + } +} diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/SPApplication.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/SPApplication.java new file mode 100644 index 00000000000..118576cfbf1 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/SPApplication.java @@ -0,0 +1,81 @@ +package io.entgra.application.mgt.common; + + +import io.entgra.application.mgt.common.response.Application; + +import java.util.List; + +public class SPApplication { + private String id; + private String name; + private String description; + private String image; + private String accessUrl; + private String access; + private String self; + private List existingApplications; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + this.image = image; + } + + public String getAccessUrl() { + return accessUrl; + } + + public void setAccessUrl(String accessUrl) { + this.accessUrl = accessUrl; + } + + public String getAccess() { + return access; + } + + public void setAccess(String access) { + this.access = access; + } + + public String getSelf() { + return self; + } + + public void setSelf(String self) { + this.self = self; + } + + public List getExistingApplications() { + return existingApplications; + } + + public void setExistingApplications(List existingApplications) { + this.existingApplications = existingApplications; + } +} diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/SPApplicationListResponse.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/SPApplicationListResponse.java new file mode 100644 index 00000000000..e638364bbde --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/SPApplicationListResponse.java @@ -0,0 +1,42 @@ +package io.entgra.application.mgt.common; + +import java.util.List; + +public class SPApplicationListResponse { + private int totalResults; + private int startIndex; + private int count; + private List applications; + + public int getTotalResults() { + return totalResults; + } + + public void setTotalResults(int totalResults) { + this.totalResults = totalResults; + } + + public int getStartIndex() { + return startIndex; + } + + public void setStartIndex(int startIndex) { + this.startIndex = startIndex; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public List getApplications() { + return applications; + } + + public void setApplications(List applications) { + this.applications = applications; + } +} diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/services/ApplicationManager.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/services/ApplicationManager.java index 5e77584b9a2..75708c11058 100644 --- a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/services/ApplicationManager.java +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/services/ApplicationManager.java @@ -16,6 +16,10 @@ */ package io.entgra.application.mgt.common.services; +import io.entgra.application.mgt.common.ApplicationType; +import io.entgra.application.mgt.common.Base64File; +import io.entgra.application.mgt.common.dto.ApplicationDTO; +import io.entgra.application.mgt.common.exception.ResourceManagementException; import org.apache.cxf.jaxrs.ext.multipart.Attachment; import io.entgra.application.mgt.common.ApplicationArtifact; import io.entgra.application.mgt.common.LifecycleChanger; @@ -46,6 +50,10 @@ import java.util.List; */ public interface ApplicationManager { + + ApplicationReleaseDTO uploadEntAppReleaseArtifacts(EntAppReleaseWrapper releaseWrapper, ApplicationArtifact artifact, + String deviceType) throws ApplicationManagementException; + /*** * The method is responsible to add new application into entgra App Manager. * @@ -54,18 +62,42 @@ public interface ApplicationManager { * @return {@link Application} * @throws ApplicationManagementException Catch all other throwing exceptions and throw {@link ApplicationManagementException} */ - Application createEntApp(ApplicationWrapper applicationWrapper, ApplicationArtifact applicationArtifact) + ApplicationDTO uploadEntAppReleaseArtifacts(ApplicationWrapper applicationWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException; - Application createWebClip(WebAppWrapper webAppWrapper, ApplicationArtifact applicationArtifact) + ApplicationReleaseDTO uploadWebAppReleaseArtifacts(WebAppReleaseWrapper releaseWrapper, ApplicationArtifact artifact) + throws ApplicationManagementException, ResourceManagementException; + + ApplicationDTO uploadWebAppReleaseArtifacts(WebAppWrapper webAppWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException; - Application createPublicApp(PublicAppWrapper publicAppWrapper, ApplicationArtifact applicationArtifact) + ApplicationReleaseDTO uploadPubAppReleaseArtifacts(PublicAppReleaseWrapper releaseWrapper, ApplicationArtifact artifact, + String deviceType) throws ResourceManagementException; + + ApplicationDTO uploadPublicAppReleaseArtifacts(PublicAppWrapper publicAppWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException; - Application createCustomApp(CustomAppWrapper customAppWrapper, ApplicationArtifact applicationArtifact) + ApplicationReleaseDTO uploadCustomAppReleaseArtifacts(CustomAppReleaseWrapper releaseWrapper, ApplicationArtifact artifact, + String deviceType) throws ResourceManagementException, ApplicationManagementException; + + ApplicationDTO uploadCustomAppReleaseArtifactsAndConstructAppDTO(CustomAppWrapper customAppWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + /*** + * This method is responsible to add application data into APPM database. However, before call this method it is + * required to do the validation of request and check the existence of application releaseDTO. + * + * @param applicationDTO Application DTO object. + * @return {@link Application} + * @throws ApplicationManagementException which throws if error occurs while during application management. + */ + Application executeApplicationPersistenceTransaction(ApplicationDTO applicationDTO) throws + ApplicationManagementException; + + + Application persistApplication(ApplicationDTO applicationDTO) throws ApplicationManagementException; + + /** * Check the existence of an application for given application name and the device type. * @@ -77,6 +109,7 @@ public interface ApplicationManager { */ boolean isExistingAppName(String appName, String deviceTypeName) throws ApplicationManagementException; + /** * Updates an already existing application. * @@ -121,6 +154,12 @@ public interface ApplicationManager { */ ApplicationList getApplications(Filter filter) throws ApplicationManagementException; + boolean isHideableApp(List applicationReleaseDTOs) + throws ApplicationManagementException; + + boolean isDeletableApp(List applicationReleaseDTOs) + throws ApplicationManagementException; + /** * To get list of applications that application releases has given package names. * @@ -131,6 +170,21 @@ public interface ApplicationManager { */ List getApplications(List packageNames) throws ApplicationManagementException; + + /** + * To create an application release for an ApplicationDTO. + * + * @param applicationDTO ApplicationDTO of the release + * @param applicationReleaseDTO ApplicatonRelease that need to be be created. + * @param type {@link ApplicationType} + * @return the unique id of the application release, if the application release succeeded else -1 + */ + ApplicationRelease createRelease(ApplicationDTO applicationDTO, ApplicationReleaseDTO applicationReleaseDTO, + ApplicationType type) + throws ApplicationManagementException; + + ApplicationDTO getApplication(int applicationId) throws ApplicationManagementException; + /** * To get the Application for given Id. * @@ -202,16 +256,6 @@ public interface ApplicationManager { void updateApplicationArtifact(String deviceType, String uuid, ApplicationArtifact applicationArtifact) throws ApplicationManagementException; - /** - * To create an application release for an ApplicationDTO. - * - * @param applicationId ID of the ApplicationDTO - * @param entAppReleaseWrapper ApplicatonRelease that need to be be created. - * @return the unique id of the application release, if the application release succeeded else -1 - */ - ApplicationRelease createEntAppRelease(int applicationId, EntAppReleaseWrapper entAppReleaseWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException; - /*** * * @param releaseUuid UUID of the application release. @@ -220,30 +264,34 @@ public interface ApplicationManager { * @return If the application release is updated correctly True returns, otherwise retuen False */ ApplicationRelease updateEntAppRelease(String releaseUuid, EntAppReleaseWrapper entAppReleaseWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; ApplicationRelease updatePubAppRelease(String releaseUuid, PublicAppReleaseWrapper publicAppReleaseWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; ApplicationRelease updateWebAppRelease(String releaseUuid, WebAppReleaseWrapper webAppReleaseWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; ApplicationRelease updateCustomAppRelease(String releaseUuid, CustomAppReleaseWrapper customAppReleaseWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException; + ApplicationArtifact applicationArtifact) throws ApplicationManagementException; /*** * To validate the application creating request * */ - void validateAppCreatingRequest(T param) throws ApplicationManagementException; + void validateAppCreatingRequest(T param, boolean isReleaseRequired) throws ApplicationManagementException; /*** * * @throws ApplicationManagementException throws if payload does not satisfy requirements. */ - void validateReleaseCreatingRequest(T param, String deviceType) throws ApplicationManagementException; + void validateReleaseCreatingRequest(T releases, String deviceType) throws ApplicationManagementException; - /*** + void validateImageArtifacts(Base64File iconFile, List screenshots) throws RequestValidatingException; + + void validateBase64File(Base64File file) throws RequestValidatingException; + + /*** * * @param iconFile Icon file for the application. * @param bannerFile Banner file for the application. @@ -253,6 +301,8 @@ public interface ApplicationManager { void validateImageArtifacts(Attachment iconFile, Attachment bannerFile, List attachmentList) throws RequestValidatingException; + void validateBinaryArtifact(Base64File binaryFile) throws RequestValidatingException; + void validateBinaryArtifact(Attachment binaryFile) throws RequestValidatingException; void addApplicationCategories(List categories) throws ApplicationManagementException; @@ -294,13 +344,13 @@ public interface ApplicationManager { void updateSubsStatus (int deviceId, int operationId, String status) throws ApplicationManagementException; - /** - * Get plist content to download and install the application. - * - * @param uuid Release UUID of the application. - * @return plist string - * @throws ApplicationManagementException Application management exception - */ + /** + * Get plist content to download and install the application. + * + * @param uuid Release UUID of the application. + * @return plist string + * @throws ApplicationManagementException Application management exception + */ String getPlistArtifact(String uuid) throws ApplicationManagementException; List getReleaseByPackageNames(List packageIds) throws ApplicationManagementException; diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/services/SPApplicationManager.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/services/SPApplicationManager.java new file mode 100644 index 00000000000..ad96347ed66 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/services/SPApplicationManager.java @@ -0,0 +1,33 @@ +package io.entgra.application.mgt.common.services; + +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.common.IdentityServerList; +import io.entgra.application.mgt.common.SPApplication; +import io.entgra.application.mgt.common.exception.ApplicationManagementException; +import io.entgra.application.mgt.common.exception.RequestValidatingException; +import io.entgra.application.mgt.common.response.Application; + +import java.util.List; + +public interface SPApplicationManager { + + + void addExistingApps(int identityServerId, List applications) throws ApplicationManagementException; + + void detachSPApplications(int identityServerId, String spUID, List appIds) throws ApplicationManagementException; + + void attachSPApplications(int identityServerId, String spUID, List appIds) throws ApplicationManagementException; + + IdentityServer getIdentityServer(int identityServerId) throws ApplicationManagementException; + + IdentityServerList getIdentityServers() throws ApplicationManagementException; + + List getSPApplications(int identityServerId, String spUID) throws ApplicationManagementException; + + Application createSPApplication(T app, int identityServerId, String spId) throws ApplicationManagementException, RequestValidatingException; + + void validateAttachAppsRequest(int identityServerId, List appIds) throws ApplicationManagementException; + + void validateDetachAppsRequest(int identityServerId, String spId, List appIds) throws ApplicationManagementException; + +} diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/ApplicationWrapper.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/ApplicationWrapper.java index f109b7b78dc..82e52cdebea 100644 --- a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/ApplicationWrapper.java +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/ApplicationWrapper.java @@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +import java.util.ArrayList; import java.util.List; @ApiModel(value = "ApplicationWrapper", description = "ApplicationWrapper represents the an ApplicationDTO in ApplicationDTO Store") @@ -80,7 +81,7 @@ public class ApplicationWrapper { value = "List of application releases", required = true) @NotNull - private List entAppReleaseWrappers; + private List entAppReleaseWrappers = new ArrayList<>(); public String getName() { diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/CustomAppReleaseWrapper.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/CustomAppReleaseWrapper.java index eb30c7e9120..adac0bf2f33 100644 --- a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/CustomAppReleaseWrapper.java +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/CustomAppReleaseWrapper.java @@ -16,10 +16,12 @@ */ package io.entgra.application.mgt.common.wrapper; +import io.entgra.application.mgt.common.Base64File; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +import java.util.List; @ApiModel(value = "CustomAppReleaseWrapper", description = "This class holds the details when releasing an Custom app release to application store") public class CustomAppReleaseWrapper { @@ -65,6 +67,18 @@ public class CustomAppReleaseWrapper { @NotNull private String packageName; + @ApiModelProperty(name = "screenshots", + value = "screenshots of the application") + private List screenshots; + + @ApiModelProperty(name = "icon", + value = "icon of the application") + private Base64File icon; + + @ApiModelProperty(name = "binaryFile", + value = "binary file of the application") + private Base64File binaryFile; + public String getReleaseType() { return releaseType; } @@ -122,4 +136,28 @@ public class CustomAppReleaseWrapper { public void setPackageName(String packageName) { this.packageName = packageName; } + + public List getScreenshots() { + return screenshots; + } + + public void setScreenshots(List screenshots) { + this.screenshots = screenshots; + } + + public Base64File getIcon() { + return icon; + } + + public void setIcon(Base64File icon) { + this.icon = icon; + } + + public Base64File getBinaryFile() { + return binaryFile; + } + + public void setBinaryFile(Base64File binaryFile) { + this.binaryFile = binaryFile; + } } diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/CustomAppWrapper.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/CustomAppWrapper.java index 4c0a392d897..b874a836614 100644 --- a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/CustomAppWrapper.java +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/CustomAppWrapper.java @@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +import java.util.ArrayList; import java.util.List; @ApiModel(value = "CustomAppWrapper", description = "CustomAppWrapper represents an Application used to install in IoT devices") @@ -78,7 +79,7 @@ public class CustomAppWrapper { value = "List of custom app releases", required = true) @NotNull - private List customAppReleaseWrappers; + private List customAppReleaseWrappers = new ArrayList<>(); public String getName() { return name; diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/EntAppReleaseWrapper.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/EntAppReleaseWrapper.java index 4d39506e9b6..2aa952ac400 100644 --- a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/EntAppReleaseWrapper.java +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/EntAppReleaseWrapper.java @@ -16,10 +16,12 @@ */ package io.entgra.application.mgt.common.wrapper; +import io.entgra.application.mgt.common.Base64File; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +import java.util.List; @ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store") public class EntAppReleaseWrapper { @@ -68,6 +70,18 @@ public class EntAppReleaseWrapper { value = "PackageName of the application installer specifically for windows") private String packageName; + @ApiModelProperty(name = "screenshots", + value = "screenshots of the application") + private List screenshots; + + @ApiModelProperty(name = "icon", + value = "icon of the application") + private Base64File icon; + + @ApiModelProperty(name = "binaryFile", + value = "binary file of the application") + private Base64File binaryFile; + public String getReleaseType() { return releaseType; } @@ -123,4 +137,28 @@ public class EntAppReleaseWrapper { public void setPackageName(String packageName) { this.packageName = packageName; } + + public List getScreenshots() { + return screenshots; + } + + public void setScreenshots(List screenshots) { + this.screenshots = screenshots; + } + + public Base64File getIcon() { + return icon; + } + + public void setIcon(Base64File icon) { + this.icon = icon; + } + + public Base64File getBinaryFile() { + return binaryFile; + } + + public void setBinaryFile(Base64File binaryFile) { + this.binaryFile = binaryFile; + } } diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/PublicAppReleaseWrapper.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/PublicAppReleaseWrapper.java index 4b60e529410..c9c5499bc27 100644 --- a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/PublicAppReleaseWrapper.java +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/PublicAppReleaseWrapper.java @@ -16,10 +16,12 @@ */ package io.entgra.application.mgt.common.wrapper; +import io.entgra.application.mgt.common.Base64File; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +import java.util.List; @ApiModel(value = "Public App Release Wrapper", description = "This class holds the details when releasing an Public App" + " Release to application store") @@ -72,6 +74,14 @@ public class PublicAppReleaseWrapper { @NotNull private String supportedOsVersions; + @ApiModelProperty(name = "screenshots", + value = "screenshots of the application") + private List screenshots; + + @ApiModelProperty(name = "icon", + value = "icon of the application") + private Base64File icon; + public String getReleaseType() { return releaseType; } @@ -123,4 +133,20 @@ public class PublicAppReleaseWrapper { public String getSupportedOsVersions() { return supportedOsVersions; } public void setSupportedOsVersions(String supportedOsVersions) { this.supportedOsVersions = supportedOsVersions; } + + public Base64File getIcon() { + return icon; + } + + public void setIcon(Base64File icon) { + this.icon = icon; + } + + public List getScreenshots() { + return screenshots; + } + + public void setScreenshots(List screenshots) { + this.screenshots = screenshots; + } } diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/PublicAppWrapper.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/PublicAppWrapper.java index 5f653257cb8..1025aa47f99 100644 --- a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/PublicAppWrapper.java +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/PublicAppWrapper.java @@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +import java.util.ArrayList; import java.util.List; @ApiModel(value = "PublicAppWrapper", description = "PublicAppWrapper represents an Application in App Store") @@ -77,8 +78,7 @@ public class PublicAppWrapper { @ApiModelProperty(name = "applicationReleaseWrappers", value = "List of public app releases", required = true) - @NotNull - private List publicAppReleaseWrappers; + private List publicAppReleaseWrappers = new ArrayList<>(); public String getName() { return name; diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/WebAppReleaseWrapper.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/WebAppReleaseWrapper.java index 090307a32de..b2a8c2f3e46 100644 --- a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/WebAppReleaseWrapper.java +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/WebAppReleaseWrapper.java @@ -16,10 +16,12 @@ */ package io.entgra.application.mgt.common.wrapper; +import io.entgra.application.mgt.common.Base64File; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +import java.util.List; @ApiModel(value = "ApplicationReleaseDTO", description = "This class holds the details when releasing an ApplicationDTO to application store") public class WebAppReleaseWrapper { @@ -63,6 +65,14 @@ public class WebAppReleaseWrapper { @NotNull private String url; + @ApiModelProperty(name = "screenshots", + value = "screenshots of the application") + private List screenshots; + + @ApiModelProperty(name = "icon", + value = "icon of the application") + private Base64File icon; + public String getReleaseType() { return releaseType; } @@ -114,4 +124,20 @@ public class WebAppReleaseWrapper { public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } + + public List getScreenshots() { + return screenshots; + } + + public void setScreenshots(List screenshots) { + this.screenshots = screenshots; + } + + public Base64File getIcon() { + return icon; + } + + public void setIcon(Base64File icon) { + this.icon = icon; + } } diff --git a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/WebAppWrapper.java b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/WebAppWrapper.java index 8455f0ce672..e6f02593adb 100644 --- a/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/WebAppWrapper.java +++ b/components/application-mgt/io.entgra.application.mgt.common/src/main/java/io/entgra/application/mgt/common/wrapper/WebAppWrapper.java @@ -20,6 +20,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import javax.validation.constraints.NotNull; +import java.util.ArrayList; import java.util.List; @ApiModel(value = "WebAppWrapper", description = "WebAppWrapper represents an ApplicationDTO in ApplicationDTO Store") @@ -78,7 +79,7 @@ public class WebAppWrapper { value = "List of web clip releases", required = true) @NotNull - private List webAppReleaseWrappers; + private List webAppReleaseWrappers = new ArrayList<>(); public String getName() { return name; diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/config/Extension.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/config/Extension.java index 282f051889d..98741a5efdc 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/config/Extension.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/config/Extension.java @@ -77,6 +77,7 @@ public class Extension { * ApplicationManagement Extensions. */ public enum Name { + SPApplicationManager, ApplicationManager, ApplicationReleaseManager, CategoryManager, diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/SPApplicationDAO.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/SPApplicationDAO.java new file mode 100644 index 00000000000..878a032be09 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/SPApplicationDAO.java @@ -0,0 +1,53 @@ +package io.entgra.application.mgt.core.dao; + +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.common.dto.ApplicationDTO; +import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException; + +import java.util.List; + +public interface SPApplicationDAO { + /** + * + * @param tenantId + * @return the application with the provided installer location + * @throws ApplicationManagementDAOException + */ + List getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException; + + /** + * + * @param tenantId + * @return the application with the provided installer location + * @throws ApplicationManagementDAOException + */ + int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException; + + /** + * + * @param tenantId + * @return the application with the provided installer location + * @throws ApplicationManagementDAOException + */ + void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException; + + List getIdentityServers(int tenantId) throws ApplicationManagementDAOException; + + IdentityServer getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException; + + /** + * Verify whether application exist for given application name and device type. Because a name and device type is + * unique for an application. + * + * @param appId id of the application. + * @param spUID UID of the service provider. + * @param tenantId ID of the tenant. + * @return ID of the ApplicationDTO. + * @throws ApplicationManagementDAOException Application Management DAO Exception. + */ + boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException; + + void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException; + + +} diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/common/ApplicationManagementDAOFactory.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/common/ApplicationManagementDAOFactory.java index 414ca0d0153..9352a12aeb1 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/common/ApplicationManagementDAOFactory.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/common/ApplicationManagementDAOFactory.java @@ -17,6 +17,11 @@ */ package io.entgra.application.mgt.core.dao.common; +import io.entgra.application.mgt.core.dao.SPApplicationDAO; +import io.entgra.application.mgt.core.dao.impl.application.spapplication.GenericSPApplicationDAOImpl; +import io.entgra.application.mgt.core.dao.impl.application.spapplication.OracleSPApplicationDAOImpl; +import io.entgra.application.mgt.core.dao.impl.application.spapplication.PostgreSQLSPApplicationDAOImpl; +import io.entgra.application.mgt.core.dao.impl.application.spapplication.SQLServerSPApplicationDAOImpl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import io.entgra.application.mgt.common.exception.UnsupportedDatabaseEngineException; @@ -101,6 +106,25 @@ public class ApplicationManagementDAOFactory { throw new IllegalStateException("Database engine has not initialized properly."); } + public static SPApplicationDAO getSPApplicationDAO() { + if (databaseEngine != null) { + switch (databaseEngine) { + case Constants.DataBaseTypes.DB_TYPE_H2: + case Constants.DataBaseTypes.DB_TYPE_MYSQL: + return new GenericSPApplicationDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_POSTGRESQL: + return new PostgreSQLSPApplicationDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerSPApplicationDAOImpl(); + case Constants.DataBaseTypes.DB_TYPE_ORACLE: + return new OracleSPApplicationDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); + } + public static LifecycleStateDAO getLifecycleStateDAO() { if (databaseEngine != null) { switch (databaseEngine) { diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java index 9fa9743590b..9972fb05cc4 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java @@ -17,6 +17,9 @@ */ package io.entgra.application.mgt.core.dao.impl.application; +import io.entgra.application.mgt.common.ApplicationType; +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.core.util.Constants; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -137,12 +140,12 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, " + "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE " + "FROM AP_APP " - + "INNER JOIN AP_APP_RELEASE ON " + + "LEFT JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + "INNER JOIN (SELECT AP_APP.ID FROM AP_APP "; if (StringUtils.isNotEmpty(filter.getVersion()) || StringUtils.isNotEmpty(filter.getAppReleaseState()) || StringUtils.isNotEmpty(filter.getAppReleaseType())) { - sql += "INNER JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "; + sql += "LEFT JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "; } sql += "WHERE AP_APP.TENANT_ID = ? "; @@ -183,7 +186,7 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic sql += "LIMIT ? OFFSET ? "; } sql += ") AS app_data ON app_data.ID = AP_APP.ID " - + "INNER JOIN (" + + "LEFT JOIN (" + "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID " + "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) " @@ -351,6 +354,7 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic } } + @Override public ApplicationDTO getApplication(String releaseUuid, int tenantId) throws ApplicationManagementDAOException { if (log.isDebugEnabled()) { @@ -609,7 +613,7 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + "FROM AP_APP " - + "INNER JOIN AP_APP_RELEASE ON " + + "LEFT JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND " + "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID " + "WHERE " diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java index 60e49f2a270..afc6a8cf412 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java @@ -83,12 +83,12 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl { + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, " + "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE " + "FROM AP_APP " - + "INNER JOIN AP_APP_RELEASE ON " + + "LEFT JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + "INNER JOIN (SELECT AP_APP.ID FROM AP_APP ORDER BY ID "; if (StringUtils.isNotEmpty(filter.getVersion()) || StringUtils.isNotEmpty(filter.getAppReleaseState()) || StringUtils.isNotEmpty(filter.getAppReleaseType())) { - sql += "INNER JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "; + sql += "LEFT JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "; } if (StringUtils.isNotEmpty(filter.getAppType())) { sql += "AND AP_APP.TYPE = ? "; @@ -127,7 +127,7 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl { sql += "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY "; } sql += ") AS app_data ON app_data.ID = AP_APP.ID " - + "INNER JOIN (" + + "LEFT JOIN (" + "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID " + "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) " diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java index 7420b9a0574..0212de34290 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java @@ -82,12 +82,12 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl { + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, " + "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE " + "FROM AP_APP " - + "INNER JOIN AP_APP_RELEASE ON " + + "LEFT JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + "INNER JOIN (SELECT AP_APP.ID FROM AP_APP "; if (StringUtils.isNotEmpty(filter.getVersion()) || StringUtils.isNotEmpty(filter.getAppReleaseState()) || StringUtils.isNotEmpty(filter.getAppReleaseType())) { - sql += "INNER JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "; + sql += "LEFT JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "; } if (StringUtils.isNotEmpty(filter.getAppType())) { sql += "AND AP_APP.TYPE = ? "; @@ -126,7 +126,7 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl { sql += "ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY "; } sql += ") AS app_data ON app_data.ID = AP_APP.ID " - + "INNER JOIN (" + + "LEFT JOIN (" + "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID " + "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) " diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/GenericSPApplicationDAOImpl.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/GenericSPApplicationDAOImpl.java new file mode 100644 index 00000000000..f7ab51eef05 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/GenericSPApplicationDAOImpl.java @@ -0,0 +1,290 @@ +package io.entgra.application.mgt.core.dao.impl.application.spapplication; + +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.common.dto.ApplicationDTO; +import io.entgra.application.mgt.common.exception.DBConnectionException; +import io.entgra.application.mgt.core.dao.SPApplicationDAO; +import io.entgra.application.mgt.core.dao.impl.AbstractDAOImpl; +import io.entgra.application.mgt.core.dao.impl.application.GenericApplicationDAOImpl; +import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException; +import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException; +import io.entgra.application.mgt.core.util.DAOUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; + +public class GenericSPApplicationDAOImpl extends AbstractDAOImpl implements SPApplicationDAO { + + private static final Log log = LogFactory.getLog(GenericApplicationDAOImpl.class); + @Override + public List getIdentityServers(int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT * " + + "FROM AP_IDENTITY_SERVER " + + "WHERE TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved available identity servers" ); + } + return DAOUtil.loadIdentityServers(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public IdentityServer getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT * " + + "FROM AP_IDENTITY_SERVER " + + "WHERE TENANT_ID = ? AND " + + "ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, tenantId); + stmt.setInt(2, id); + try (ResultSet rs = stmt.executeQuery()){ + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved available identity servers" ); + } + return DAOUtil.loadIdentityServer(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (UnexpectedServerErrorException e) { + String msg = "Found more than one identity server for id: " + id; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public List getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting identity server applications from the database"); + } + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "LEFT JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND " + + "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID " + + "INNER JOIN AP_IS_SP_APP_MAPPING as SP_APPS on SP_APPS.AP_APP_ID = AP_APP.ID " + + "WHERE " + + "SP_APPS.SP_UID = ? " + + "AND SP_APPS.IS_ID = ? " + + "AND AP_APP.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, spUID); + stmt.setInt(2, identityServerId); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved basic details of the identity server applications"); + } + return DAOUtil.loadApplications(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get identity server applications for application release"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting identity server applications while executing query. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT AP_APP_ID AS ID " + + "FROM AP_IS_SP_APP_MAPPING SP_MAPPING " + + "WHERE " + + "SP_UID = ? AND AP_APP_ID = ? " + + "AND IS_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to check whether the existence of " + + "sp application with id " + appId + " for service provider which has UID " + spUID; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to check whether the existence of service provider application " + + "with id " + appId + " for service provider which has UID " + spUID + ". executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to map an application wit identity server:service provider"); + log.debug("Application Details : "); + log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId); + } + String sql = "DELETE FROM AP_IS_SP_APP_MAPPING " + + "WHERE SP_UID = ? " + + "AND AP_APP_ID = ? " + + "AND IS_ID = ? " + + "AND TENANT_ID = ? "; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to map an application wit identity server:service provider"); + log.debug("Application Details : "); + log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId); + } + String sql = "INSERT INTO AP_IS_SP_APP_MAPPING " + + "(SP_UID, " + + "AP_APP_ID, " + + "IS_ID, TENANT_ID) " + + "VALUES (?, ?, ?, ?)"; + int mappingId = -1; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + try (ResultSet rs = stmt.getGeneratedKeys()) { + if (rs.next()) { + mappingId = rs.getInt(1); + } + return mappingId; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete application with the id: " + applicationId + " from service providers"); + } + String sql = "DELETE FROM AP_IS_SP_APP_MAPPING WHERE AP_APP_ID = ? AND TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setInt(1, applicationId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + +} diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/OracleSPApplicationDAOImpl.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/OracleSPApplicationDAOImpl.java new file mode 100644 index 00000000000..553daa263c0 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/OracleSPApplicationDAOImpl.java @@ -0,0 +1,289 @@ +package io.entgra.application.mgt.core.dao.impl.application.spapplication; + +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.common.dto.ApplicationDTO; +import io.entgra.application.mgt.common.exception.DBConnectionException; +import io.entgra.application.mgt.core.dao.SPApplicationDAO; +import io.entgra.application.mgt.core.dao.impl.AbstractDAOImpl; +import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException; +import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException; +import io.entgra.application.mgt.core.util.DAOUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; + +public class OracleSPApplicationDAOImpl extends AbstractDAOImpl implements SPApplicationDAO { + + private static final Log log = LogFactory.getLog(OracleSPApplicationDAOImpl.class); + + @Override + public List getIdentityServers(int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT * " + + "FROM AP_IDENTITY_SERVER " + + "WHERE TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved available identity servers" ); + } + return DAOUtil.loadIdentityServers(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public IdentityServer getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT * " + + "FROM AP_IDENTITY_SERVER " + + "WHERE TENANT_ID = ? AND " + + "ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, tenantId); + stmt.setInt(2, id); + try (ResultSet rs = stmt.executeQuery()){ + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved available identity servers" ); + } + return DAOUtil.loadIdentityServer(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (UnexpectedServerErrorException e) { + String msg = "Found more than one identity server for id: " + id; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public List getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting identity server applications from the database"); + } + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "LEFT JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND " + + "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID " + + "INNER JOIN AP_IS_SP_APP_MAPPING as SP_APPS on SP_APPS.AP_APP_ID = AP_APP.ID " + + "WHERE " + + "SP_APPS.SP_UID = ? " + + "AND SP_APPS.IS_ID = ? " + + "AND AP_APP.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, spUID); + stmt.setInt(2, identityServerId); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved basic details of the identity server applications"); + } + return DAOUtil.loadApplications(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get identity server applications for application release"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting identity server applications while executing query. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT AP_APP_ID AS ID " + + "FROM AP_IS_SP_APP_MAPPING SP_MAPPING " + + "WHERE " + + "SP_UID = ? AND AP_APP_ID = ? " + + "AND IS_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to check whether the existence of " + + "sp application with id " + appId + " for service provider which has UID " + spUID; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to check whether the existence of service provider application " + + "with id " + appId + " for service provider which has UID " + spUID + ". executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to map an application wit identity server:service provider"); + log.debug("Application Details : "); + log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId); + } + String sql = "DELETE FROM AP_IS_SP_APP_MAPPING " + + "WHERE SP_UID = ? " + + "AND AP_APP_ID = ? " + + "AND IS_ID = ? " + + "AND TENANT_ID = ? "; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to map an application wit identity server:service provider"); + log.debug("Application Details : "); + log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId); + } + String sql = "INSERT INTO AP_IS_SP_APP_MAPPING " + + "(SP_UID, " + + "AP_APP_ID, " + + "IS_ID, TENANT_ID) " + + "VALUES (?, ?, ?, ?)"; + int mappingId = -1; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + try (ResultSet rs = stmt.getGeneratedKeys()) { + if (rs.next()) { + mappingId = rs.getInt(1); + } + return mappingId; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete application with the id: " + applicationId + " from service providers"); + } + String sql = "DELETE FROM AP_IS_SP_APP_MAPPING WHERE AP_APP_ID = ? AND TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setInt(1, applicationId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + +} diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/PostgreSQLSPApplicationDAOImpl.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/PostgreSQLSPApplicationDAOImpl.java new file mode 100644 index 00000000000..309c77b1d86 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/PostgreSQLSPApplicationDAOImpl.java @@ -0,0 +1,289 @@ +package io.entgra.application.mgt.core.dao.impl.application.spapplication; + +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.common.dto.ApplicationDTO; +import io.entgra.application.mgt.common.exception.DBConnectionException; +import io.entgra.application.mgt.core.dao.SPApplicationDAO; +import io.entgra.application.mgt.core.dao.impl.AbstractDAOImpl; +import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException; +import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException; +import io.entgra.application.mgt.core.util.DAOUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; + +public class PostgreSQLSPApplicationDAOImpl extends AbstractDAOImpl implements SPApplicationDAO { + + private static final Log log = LogFactory.getLog(PostgreSQLSPApplicationDAOImpl.class); + + @Override + public List getIdentityServers(int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT * " + + "FROM AP_IDENTITY_SERVER " + + "WHERE TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved available identity servers" ); + } + return DAOUtil.loadIdentityServers(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public IdentityServer getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT * " + + "FROM AP_IDENTITY_SERVER " + + "WHERE TENANT_ID = ? AND " + + "ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, tenantId); + stmt.setInt(2, id); + try (ResultSet rs = stmt.executeQuery()){ + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved available identity servers" ); + } + return DAOUtil.loadIdentityServer(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (UnexpectedServerErrorException e) { + String msg = "Found more than one identity server for id: " + id; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public List getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting identity server applications from the database"); + } + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "LEFT JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND " + + "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID " + + "INNER JOIN AP_IS_SP_APP_MAPPING as SP_APPS on SP_APPS.AP_APP_ID = AP_APP.ID " + + "WHERE " + + "SP_APPS.SP_UID = ? " + + "AND SP_APPS.IS_ID = ? " + + "AND AP_APP.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, spUID); + stmt.setInt(2, identityServerId); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved basic details of the identity server applications"); + } + return DAOUtil.loadApplications(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get identity server applications for application release"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting identity server applications while executing query. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT AP_APP_ID AS ID " + + "FROM AP_IS_SP_APP_MAPPING SP_MAPPING " + + "WHERE " + + "SP_UID = ? AND AP_APP_ID = ? " + + "AND IS_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to check whether the existence of " + + "sp application with id " + appId + " for service provider which has UID " + spUID; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to check whether the existence of service provider application " + + "with id " + appId + " for service provider which has UID " + spUID + ". executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to map an application wit identity server:service provider"); + log.debug("Application Details : "); + log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId); + } + String sql = "DELETE FROM AP_IS_SP_APP_MAPPING " + + "WHERE SP_UID = ? " + + "AND AP_APP_ID = ? " + + "AND IS_ID = ? " + + "AND TENANT_ID = ? "; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to map an application wit identity server:service provider"); + log.debug("Application Details : "); + log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId); + } + String sql = "INSERT INTO AP_IS_SP_APP_MAPPING " + + "(SP_UID, " + + "AP_APP_ID, " + + "IS_ID, TENANT_ID) " + + "VALUES (?, ?, ?, ?)"; + int mappingId = -1; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + try (ResultSet rs = stmt.getGeneratedKeys()) { + if (rs.next()) { + mappingId = rs.getInt(1); + } + return mappingId; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete application with the id: " + applicationId + " from service providers"); + } + String sql = "DELETE FROM AP_IS_SP_APP_MAPPING WHERE AP_APP_ID = ? AND TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setInt(1, applicationId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + +} diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/SQLServerSPApplicationDAOImpl.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/SQLServerSPApplicationDAOImpl.java new file mode 100644 index 00000000000..e31be220275 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/dao/impl/application/spapplication/SQLServerSPApplicationDAOImpl.java @@ -0,0 +1,289 @@ +package io.entgra.application.mgt.core.dao.impl.application.spapplication; + +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.common.dto.ApplicationDTO; +import io.entgra.application.mgt.common.exception.DBConnectionException; +import io.entgra.application.mgt.core.dao.SPApplicationDAO; +import io.entgra.application.mgt.core.dao.impl.AbstractDAOImpl; +import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException; +import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException; +import io.entgra.application.mgt.core.util.DAOUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.List; + +public class SQLServerSPApplicationDAOImpl extends AbstractDAOImpl implements SPApplicationDAO { + + private static final Log log = LogFactory.getLog(SQLServerSPApplicationDAOImpl.class); + + @Override + public List getIdentityServers(int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT * " + + "FROM AP_IDENTITY_SERVER " + + "WHERE TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved available identity servers" ); + } + return DAOUtil.loadIdentityServers(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public IdentityServer getIdentityServerById(int id, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT * " + + "FROM AP_IDENTITY_SERVER " + + "WHERE TENANT_ID = ? AND " + + "ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setInt(1, tenantId); + stmt.setInt(2, id); + try (ResultSet rs = stmt.executeQuery()){ + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved available identity servers" ); + } + return DAOUtil.loadIdentityServer(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to retrieve available identity servers"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (UnexpectedServerErrorException e) { + String msg = "Found more than one identity server for id: " + id; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public List getSPApplications(int identityServerId, String spUID, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Getting identity server applications from the database"); + } + String sql = "SELECT " + + "AP_APP.ID AS APP_ID, " + + "AP_APP.NAME AS APP_NAME, " + + "AP_APP.DESCRIPTION AS APP_DESCRIPTION, " + + "AP_APP.TYPE AS APP_TYPE, " + + "AP_APP.STATUS AS APP_STATUS, " + + "AP_APP.SUB_TYPE AS APP_SUB_TYPE, " + + "AP_APP.CURRENCY AS APP_CURRENCY, " + + "AP_APP.RATING AS APP_RATING, " + + "AP_APP.DEVICE_TYPE_ID AS APP_DEVICE_TYPE_ID, " + + "AP_APP_RELEASE.ID AS RELEASE_ID, " + + "AP_APP_RELEASE.DESCRIPTION AS RELEASE_DESCRIPTION, " + + "AP_APP_RELEASE.VERSION AS RELEASE_VERSION, " + + "AP_APP_RELEASE.UUID AS RELEASE_UUID, " + + "AP_APP_RELEASE.RELEASE_TYPE AS RELEASE_TYPE, " + + "AP_APP_RELEASE.INSTALLER_LOCATION AS AP_RELEASE_STORED_LOC, " + + "AP_APP_RELEASE.ICON_LOCATION AS AP_RELEASE_ICON_LOC, " + + "AP_APP_RELEASE.BANNER_LOCATION AS AP_RELEASE_BANNER_LOC, " + + "AP_APP_RELEASE.SC_1_LOCATION AS AP_RELEASE_SC1, " + + "AP_APP_RELEASE.SC_2_LOCATION AS AP_RELEASE_SC2, " + + "AP_APP_RELEASE.SC_3_LOCATION AS AP_RELEASE_SC3, " + + "AP_APP_RELEASE.APP_HASH_VALUE AS RELEASE_HASH_VALUE, " + + "AP_APP_RELEASE.APP_PRICE AS RELEASE_PRICE, " + + "AP_APP_RELEASE.APP_META_INFO AS RELEASE_META_INFO, " + + "AP_APP_RELEASE.PACKAGE_NAME AS PACKAGE_NAME, " + + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "FROM AP_APP " + + "LEFT JOIN AP_APP_RELEASE ON " + + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID AND " + + "AP_APP.TENANT_ID = AP_APP_RELEASE.TENANT_ID " + + "INNER JOIN AP_IS_SP_APP_MAPPING as SP_APPS on SP_APPS.AP_APP_ID = AP_APP.ID " + + "WHERE " + + "SP_APPS.SP_UID = ? " + + "AND SP_APPS.IS_ID = ? " + + "AND AP_APP.TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, spUID); + stmt.setInt(2, identityServerId); + stmt.setInt(3, tenantId); + try (ResultSet rs = stmt.executeQuery()) { + if (log.isDebugEnabled()) { + log.debug("Successfully retrieved basic details of the identity server applications"); + } + return DAOUtil.loadApplications(rs); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to get identity server applications for application release"; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while getting identity server applications while executing query. Executed query: " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public boolean isSPApplicationExist(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + String sql = "SELECT AP_APP_ID AS ID " + + "FROM AP_IS_SP_APP_MAPPING SP_MAPPING " + + "WHERE " + + "SP_UID = ? AND AP_APP_ID = ? " + + "AND IS_ID = ? AND " + + "TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql)){ + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + try (ResultSet rs = stmt.executeQuery()){ + return rs.next(); + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to check whether the existence of " + + "sp application with id " + appId + " for service provider which has UID " + spUID; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing query to check whether the existence of service provider application " + + "with id " + appId + " for service provider which has UID " + spUID + ". executed query " + sql; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + + } + + @Override + public void detachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to map an application wit identity server:service provider"); + log.debug("Application Details : "); + log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId); + } + String sql = "DELETE FROM AP_IS_SP_APP_MAPPING " + + "WHERE SP_UID = ? " + + "AND AP_APP_ID = ? " + + "AND IS_ID = ? " + + "AND TENANT_ID = ? "; + + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public int attachSPApplication(int identityServerId, String spUID, int appId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to map an application wit identity server:service provider"); + log.debug("Application Details : "); + log.debug("App ID : " + appId + " SP UID : " + spUID + " IS ID : " + identityServerId); + } + String sql = "INSERT INTO AP_IS_SP_APP_MAPPING " + + "(SP_UID, " + + "AP_APP_ID, " + + "IS_ID, TENANT_ID) " + + "VALUES (?, ?, ?, ?)"; + int mappingId = -1; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, spUID); + stmt.setInt(2, appId); + stmt.setInt(3, identityServerId); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + try (ResultSet rs = stmt.getGeneratedKeys()) { + if (rs.next()) { + mappingId = rs.getInt(1); + } + return mappingId; + } + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + appId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + + @Override + public void deleteApplicationFromServiceProviders(int applicationId, int tenantId) throws ApplicationManagementDAOException { + if (log.isDebugEnabled()) { + log.debug("Request received in DAO Layer to delete application with the id: " + applicationId + " from service providers"); + } + String sql = "DELETE FROM AP_IS_SP_APP_MAPPING WHERE AP_APP_ID = ? AND TENANT_ID = ?"; + try { + Connection conn = this.getDBConnection(); + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setInt(1, applicationId); + stmt.setInt(2, tenantId); + stmt.executeUpdate(); + } + } catch (DBConnectionException e) { + String msg = "Error occurred while obtaining the DB connection to create an sp application mapping which has " + + "application id " + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } catch (SQLException e) { + String msg = "Error occurred while executing SQL to create an application which has application id " + + applicationId; + log.error(msg, e); + throw new ApplicationManagementDAOException(msg, e); + } + } + +} diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/impl/ApplicationManagerImpl.java index 82405ee2fe9..f413fee76ce 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/impl/ApplicationManagerImpl.java @@ -17,6 +17,8 @@ package io.entgra.application.mgt.core.impl; +import io.entgra.application.mgt.common.Base64File; +import io.entgra.application.mgt.core.dao.SPApplicationDAO; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringEscapeUtils; @@ -109,8 +111,7 @@ import java.util.stream.Stream; /** * Default Concrete implementation of Application Management related implementations. */ -public class -ApplicationManagerImpl implements ApplicationManager { +public class ApplicationManagerImpl implements ApplicationManager { private static final Log log = LogFactory.getLog(ApplicationManagerImpl.class); private VisibilityDAO visibilityDAO; @@ -119,6 +120,7 @@ ApplicationManagerImpl implements ApplicationManager { private LifecycleStateDAO lifecycleStateDAO; private SubscriptionDAO subscriptionDAO; private LifecycleStateManager lifecycleStateManager; + private SPApplicationDAO spApplicationDAO; public ApplicationManagerImpl() { initDataAccessObjects(); @@ -131,11 +133,21 @@ ApplicationManagerImpl implements ApplicationManager { this.lifecycleStateDAO = ApplicationManagementDAOFactory.getLifecycleStateDAO(); this.applicationReleaseDAO = ApplicationManagementDAOFactory.getApplicationReleaseDAO(); this.subscriptionDAO = ApplicationManagementDAOFactory.getSubscriptionDAO(); + this.spApplicationDAO = ApplicationManagementDAOFactory.getSPApplicationDAO(); } @Override - public Application createEntApp(ApplicationWrapper applicationWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + public ApplicationReleaseDTO uploadEntAppReleaseArtifacts(EntAppReleaseWrapper releaseWrapper, ApplicationArtifact artifact, + String deviceType) throws ApplicationManagementException { + ApplicationReleaseDTO releaseDTO = APIUtil.releaseWrapperToReleaseDTO(releaseWrapper); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + return uploadEntAppReleaseArtifacts(releaseDTO, artifact, deviceType, tenantId, true); + } + + @Override + public ApplicationDTO uploadEntAppReleaseArtifacts(ApplicationWrapper applicationWrapper, + ApplicationArtifact applicationArtifact) + throws ApplicationManagementException{ if (log.isDebugEnabled()) { log.debug("Ent. Application create request is received. Application name: " + applicationWrapper.getName() + " Device type: " + applicationWrapper.getDeviceType()); @@ -149,12 +161,21 @@ ApplicationManagerImpl implements ApplicationManager { applicationWrapper.getDeviceType(), tenantId, false); applicationDTO.getApplicationReleaseDTOs().clear(); applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); - return addAppDataIntoDB(applicationDTO, tenantId); + return applicationDTO; } @Override - public Application createWebClip(WebAppWrapper webAppWrapper, ApplicationArtifact applicationArtifact) - throws ApplicationManagementException { + public ApplicationReleaseDTO uploadWebAppReleaseArtifacts(WebAppReleaseWrapper releaseWrapper, ApplicationArtifact artifact) + throws ResourceManagementException { + ApplicationReleaseDTO releaseDTO = APIUtil.releaseWrapperToReleaseDTO(releaseWrapper); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + return uploadWebAppReleaseArtifacts(releaseDTO, artifact, tenantId); + } + + @Override + public ApplicationDTO uploadWebAppReleaseArtifacts(WebAppWrapper webAppWrapper, + ApplicationArtifact applicationArtifact) + throws ApplicationManagementException{ if (log.isDebugEnabled()) { log.debug("Web clip create request is received. App name: " + webAppWrapper.getName() + " Device type: " + Constants.ANY); @@ -162,25 +183,38 @@ ApplicationManagerImpl implements ApplicationManager { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(webAppWrapper); ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); - applicationReleaseDTO.setUuid(UUID.randomUUID().toString()); - applicationReleaseDTO.setAppHashValue(DigestUtils.md5Hex(applicationReleaseDTO.getInstallerName())); - //uploading application artifacts try { applicationDTO.getApplicationReleaseDTOs().clear(); - applicationDTO.getApplicationReleaseDTOs() - .add(addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId)); + applicationDTO.getApplicationReleaseDTOs().add(uploadWebAppReleaseArtifacts(applicationReleaseDTO, applicationArtifact, tenantId)); + return applicationDTO; } catch (ResourceManagementException e) { - String msg = "Error Occured when uploading artifacts of the web clip: " + webAppWrapper.getName(); + String msg = "Error Occurred when uploading artifacts of the web clip: " + webAppWrapper.getName(); log.error(msg); throw new ApplicationManagementException(msg, e); } - //insert application data into database - return addAppDataIntoDB(applicationDTO, tenantId); + } + + public ApplicationReleaseDTO uploadWebAppReleaseArtifacts(ApplicationReleaseDTO releaseDTO, ApplicationArtifact applicationArtifact, + int tenantId) + throws ResourceManagementException { + releaseDTO.setUuid(UUID.randomUUID().toString()); + releaseDTO.setAppHashValue(DigestUtils.md5Hex(releaseDTO.getInstallerName())); + //uploading application artifacts + return addImageArtifacts(releaseDTO, applicationArtifact, tenantId); } @Override - public Application createPublicApp(PublicAppWrapper publicAppWrapper, ApplicationArtifact applicationArtifact) - throws ApplicationManagementException { + public ApplicationReleaseDTO uploadPubAppReleaseArtifacts(PublicAppReleaseWrapper releaseWrapper, ApplicationArtifact artifact, + String deviceType) throws ResourceManagementException { + ApplicationReleaseDTO releaseDTO = APIUtil.releaseWrapperToReleaseDTO(releaseWrapper); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + return uploadPubAppReleaseArtifacts(releaseDTO, artifact, deviceType, tenantId); + } + + @Override + public ApplicationDTO uploadPublicAppReleaseArtifacts(PublicAppWrapper publicAppWrapper, + ApplicationArtifact applicationArtifact) + throws ApplicationManagementException{ int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); if (log.isDebugEnabled()) { @@ -188,114 +222,165 @@ ApplicationManagerImpl implements ApplicationManager { + " Device Type: " + publicAppWrapper.getDeviceType()); } - String publicAppStorePath = ""; - if (DeviceTypes.ANDROID.toString().equalsIgnoreCase(publicAppWrapper.getDeviceType())) { - publicAppStorePath = Constants.GOOGLE_PLAY_STORE_URL; - } else if (DeviceTypes.IOS.toString().equals(publicAppWrapper.getDeviceType())) { - publicAppStorePath = Constants.APPLE_STORE_URL; - } ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(publicAppWrapper); ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); - String appInstallerUrl = publicAppStorePath + applicationReleaseDTO.getPackageName(); - applicationReleaseDTO.setInstallerName(appInstallerUrl); - applicationReleaseDTO.setUuid(UUID.randomUUID().toString()); - applicationReleaseDTO.setAppHashValue(DigestUtils.md5Hex(appInstallerUrl)); + validatePublicAppReleasePackageName(applicationReleaseDTO.getPackageName()); + + try { + //uploading application artifacts + applicationReleaseDTO = uploadPubAppReleaseArtifacts(applicationReleaseDTO, applicationArtifact, + publicAppWrapper.getDeviceType(), tenantId); + applicationDTO.getApplicationReleaseDTOs().clear(); + applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); + return applicationDTO; + } catch (ResourceManagementException e) { + String msg = "Error Occured when uploading artifacts of the public app: " + publicAppWrapper.getName(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + public ApplicationReleaseDTO uploadPubAppReleaseArtifacts(ApplicationReleaseDTO releaseDTO, ApplicationArtifact applicationArtifact, + String deviceType, int tenantId) + throws ResourceManagementException { + String appInstallerUrl = getPublicAppStorePath(deviceType) + releaseDTO.getPackageName(); + releaseDTO.setInstallerName(appInstallerUrl); + releaseDTO.setUuid(UUID.randomUUID().toString()); + releaseDTO.setAppHashValue(DigestUtils.md5Hex(appInstallerUrl)); + //uploading application artifacts + return addImageArtifacts(releaseDTO, applicationArtifact, tenantId); + } + public void validatePublicAppReleasePackageName(String packageName) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { ConnectionManagerUtil.openDBConnection(); List exitingPubAppReleases = applicationReleaseDAO - .getReleaseByPackages(Collections.singletonList(applicationReleaseDTO.getPackageName()), tenantId); + .getReleaseByPackages(Collections.singletonList(packageName), tenantId); if (!exitingPubAppReleases.isEmpty()){ - String msg = "Public app release exists for package name " + applicationReleaseDTO.getPackageName() + String msg = "Public app release exists for package name " + packageName + ". Hence you can't add new public app for package name " - + applicationReleaseDTO.getPackageName(); + + packageName; log.error(msg); throw new BadRequestException(msg); } } catch (ApplicationManagementDAOException e) { - String msg = "Error Occured when fetching release: " + publicAppWrapper.getName(); + String msg = "Error Occurred when fetching release: " + packageName; log.error(msg); throw new ApplicationManagementException(msg, e); } finally { ConnectionManagerUtil.closeDBConnection(); } + } - try { - //uploading application artifacts - applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); - applicationDTO.getApplicationReleaseDTOs().clear(); - applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); - } catch (ResourceManagementException e) { - String msg = "Error Occured when uploading artifacts of the public app: " + publicAppWrapper.getName(); - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } - //insert application data into database - return addAppDataIntoDB(applicationDTO, tenantId); + @Override + public ApplicationReleaseDTO uploadCustomAppReleaseArtifacts(CustomAppReleaseWrapper releaseWrapper, ApplicationArtifact artifact, + String deviceType) throws ResourceManagementException, ApplicationManagementException { + ApplicationReleaseDTO releaseDTO = APIUtil.releaseWrapperToReleaseDTO(releaseWrapper); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + return uploadCustomAppReleaseArtifacts(releaseDTO, artifact, deviceType, tenantId); } @Override - public Application createCustomApp(CustomAppWrapper customAppWrapper, ApplicationArtifact applicationArtifact) + public ApplicationDTO uploadCustomAppReleaseArtifactsAndConstructAppDTO(CustomAppWrapper customAppWrapper, + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { try { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); - ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); - byte[] content = IOUtils.toByteArray(applicationArtifact.getInstallerStream()); - String md5OfApp = StorageManagementUtil.getMD5(new ByteArrayInputStream(content)); - if (md5OfApp == null) { - String msg = - "Error occurred while getting md5sum value of custom app. Application name: " + customAppWrapper - .getName() + " Device type: " + customAppWrapper.getDeviceType(); - log.error(msg); - throw new ApplicationManagementException(msg); - } - try { - ConnectionManagerUtil.openDBConnection(); - if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(md5OfApp, tenantId)) { - String msg = "Application release exists for the uploaded binary file. Application name: " - + customAppWrapper.getName() + " Device type: " + customAppWrapper.getDeviceType(); - log.error(msg); - throw new BadRequestException(msg); - } - } catch (ApplicationManagementDAOException e) { - String msg = "Error occurred while adding application data into the database. Application name: " - + customAppWrapper.getName() + " Device type: " + customAppWrapper.getDeviceType(); - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } finally { - ConnectionManagerUtil.closeDBConnection(); - } - ApplicationDTO applicationDTO = APIUtil.convertToAppDTO(customAppWrapper); ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); - applicationReleaseDTO.setUuid(UUID.randomUUID().toString()); - applicationReleaseDTO.setAppHashValue(md5OfApp); - applicationReleaseDTO.setInstallerName(applicationArtifact.getInstallerName()); - try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) { - applicationStorageManager.uploadReleaseArtifact(applicationReleaseDTO, customAppWrapper.getDeviceType(), - binaryDuplicate, tenantId); - } catch (IOException e) { - String msg = "Error occurred when uploading release artifact into the server."; - log.error(msg); - throw new ApplicationManagementException(msg); - } - applicationReleaseDTO = addImageArtifacts(applicationReleaseDTO, applicationArtifact, tenantId); + applicationReleaseDTO = uploadCustomAppReleaseArtifacts(applicationReleaseDTO, applicationArtifact, + customAppWrapper.getDeviceType(), tenantId); applicationDTO.getApplicationReleaseDTOs().clear(); applicationDTO.getApplicationReleaseDTOs().add(applicationReleaseDTO); - return addAppDataIntoDB(applicationDTO, tenantId); + return applicationDTO; } catch (ResourceManagementException e) { String msg = "Error occurred while uploading application artifact into the server. Application name: " + customAppWrapper.getName() + " Device type: " + customAppWrapper.getDeviceType(); log.error(msg, e); throw new ApplicationManagementException(msg, e); + } + } + + public ApplicationReleaseDTO uploadCustomAppReleaseArtifacts(ApplicationReleaseDTO releaseDTO, ApplicationArtifact applicationArtifact, + String deviceType, int tenantId) + throws ResourceManagementException, ApplicationManagementException { + ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); + byte[] content = getByteContentOfApp(applicationArtifact); + String md5OfApp = generateMD5OfApp(applicationArtifact, content); + validateReleaseBinaryFileHash(md5OfApp); + releaseDTO.setUuid(UUID.randomUUID().toString()); + releaseDTO.setAppHashValue(md5OfApp); + releaseDTO.setInstallerName(applicationArtifact.getInstallerName()); + + try (ByteArrayInputStream binaryDuplicate = new ByteArrayInputStream(content)) { + applicationStorageManager.uploadReleaseArtifact(releaseDTO, deviceType, + binaryDuplicate, tenantId); } catch (IOException e) { - String msg = "Error occurred while getting bytes from application release artifact. Application name: " - + customAppWrapper.getName() + " Device type: " + customAppWrapper.getDeviceType(); + String msg = "Error occurred when uploading release artifact into the server"; + log.error(msg); + throw new ApplicationManagementException(msg); + } + return addImageArtifacts(releaseDTO, applicationArtifact, tenantId); + } + + public void validateReleaseBinaryFileHash(String hash) + throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + if (this.applicationReleaseDAO.verifyReleaseExistenceByHash(hash, tenantId)) { + String msg = "Application release already exists"; + log.error(msg); + throw new BadRequestException(msg); + } + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while checking if release already exists"; log.error(msg, e); throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + public String getPublicAppStorePath(String deviceType) { + if (DeviceTypes.ANDROID.toString().equalsIgnoreCase(deviceType)) { + return Constants.GOOGLE_PLAY_STORE_URL; + } else if (DeviceTypes.IOS.toString().equalsIgnoreCase(deviceType)) { + return Constants.APPLE_STORE_URL; + } else { + throw new IllegalArgumentException("No such device with the name " + deviceType); } } + private byte[] getByteContentOfApp(ApplicationArtifact artifact) throws ApplicationManagementException{ + try { + return IOUtils.toByteArray(artifact.getInstallerStream()); + } catch (IOException e) { + String msg = "Error occurred while getting byte content of app binary artifact"; + log.error(msg); + throw new ApplicationManagementException(msg); + } + } + + private String generateMD5OfApp(ApplicationArtifact applicationArtifact, byte[] content) throws ApplicationManagementException { + try { + String md5OfApp = StorageManagementUtil.getMD5(new ByteArrayInputStream(content)); + if (md5OfApp == null) { + String msg = "Error occurred while generating md5sum value of " + applicationArtifact.getInstallerName(); + log.error(msg); + throw new ApplicationManagementException(msg); + } + return md5OfApp; + } catch( ApplicationStorageManagementException e) { + String msg = "Error occurred while generating md5sum value of " + applicationArtifact.getInstallerName(); + log.error(msg); + throw new ApplicationManagementException(msg); + } + } + + + /** * Delete Application release artifacts * @@ -327,7 +412,7 @@ ApplicationManagerImpl implements ApplicationManager { * @throws ApplicationManagementException if error occurred while handling application release data. */ private ApplicationReleaseDTO addApplicationReleaseArtifacts(String deviceType, - ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, boolean isNewRelease) + ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact, boolean isNewRelease) throws ResourceManagementException, ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); @@ -423,7 +508,7 @@ ApplicationManagerImpl implements ApplicationManager { * @throws ApplicationManagementException if error occurred while handling application release data. */ private ApplicationReleaseDTO updateEntAppReleaseArtifact(String deviceType, - ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact) + ApplicationReleaseDTO applicationReleaseDTO, ApplicationArtifact applicationArtifact) throws ResourceManagementException, ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); @@ -518,7 +603,7 @@ ApplicationManagerImpl implements ApplicationManager { * @throws ResourceManagementException if error occurred while uploading image artifacts into file system. */ private ApplicationReleaseDTO addImageArtifacts(ApplicationReleaseDTO applicationReleaseDTO, - ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException { + ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException { ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); applicationReleaseDTO.setIconName(applicationArtifact.getIconName()); @@ -555,7 +640,7 @@ ApplicationManagerImpl implements ApplicationManager { * @throws ResourceManagementException if error occurred while uploading application release artifacts into the file system. */ private ApplicationReleaseDTO updateImageArtifacts(ApplicationReleaseDTO applicationReleaseDTO, - ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException{ + ApplicationArtifact applicationArtifact, int tenantId) throws ResourceManagementException{ ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); if (!StringUtils.isEmpty(applicationArtifact.getIconName())) { @@ -608,6 +693,7 @@ ApplicationManagerImpl implements ApplicationManager { return applicationReleaseDTO; } + @Override public ApplicationList getApplications(Filter filter) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); @@ -665,7 +751,6 @@ ApplicationManagerImpl implements ApplicationManager { applications.add(application); } } - Pagination pagination = new Pagination(); pagination.setCount(applicationDAO.getApplicationCount(filter, deviceType.getId(), tenantId)); pagination.setSize(applications.size()); @@ -732,7 +817,6 @@ ApplicationManagerImpl implements ApplicationManager { } return true; } - /** * To check whether the application is whether hideable or not * @@ -740,7 +824,8 @@ ApplicationManagerImpl implements ApplicationManager { * @return true if application releases are in hideable state (i.e Retired), otherwise returns false * @throws ApplicationManagementException if error occurred while getting application release end state. */ - private boolean isHideableApp(List applicationReleaseDTOs) + @Override + public boolean isHideableApp(List applicationReleaseDTOs) throws ApplicationManagementException { try { for (ApplicationReleaseDTO applicationReleaseDTO : applicationReleaseDTOs) { @@ -764,7 +849,8 @@ ApplicationManagerImpl implements ApplicationManager { * @throws ApplicationManagementException if error occurred while checking whether the application release is in * deletable state or not. */ - private boolean isDeletableApp(List applicationReleaseDTOs) + @Override + public boolean isDeletableApp(List applicationReleaseDTOs) throws ApplicationManagementException { try { for (ApplicationReleaseDTO applicationReleaseDTO : applicationReleaseDTOs) { @@ -845,7 +931,7 @@ ApplicationManagerImpl implements ApplicationManager { * @throws UserStoreException if error occurred when checking whether user has assigned at least one filtering role. */ private boolean hasAppUnrestrictedRole(List appUnrestrictedRoles, List filteringUnrestrictedRoles, - String userName) throws BadRequestException, UserStoreException { + String userName) throws BadRequestException, UserStoreException { if (!hasUserRole(filteringUnrestrictedRoles, userName)) { String msg = "At least one filtering role is not assigned for the user: " + userName + ". Hence user " + userName @@ -863,44 +949,62 @@ ApplicationManagerImpl implements ApplicationManager { return false; } - /*** - * This method is responsible to add application data into APPM database. However, before call this method it is - * required to do the validation of request and check the existence of application releaseDTO. - * - * @param applicationDTO Application DTO object. - * @param tenantId Tenant Id - * @return {@link Application} - * @throws ApplicationManagementException which throws if error occurs while during application management. - */ - private Application addAppDataIntoDB(ApplicationDTO applicationDTO, int tenantId) throws ApplicationManagementException { - ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); - List unrestrictedRoles = applicationDTO.getUnrestrictedRoles(); - ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); - List categories = applicationDTO.getAppCategories(); - List tags = applicationDTO.getTags(); - List applicationReleaseEntities = new ArrayList<>(); + @Override + public Application persistApplication(ApplicationDTO applicationDTO) throws ApplicationManagementException { try { ConnectionManagerUtil.beginDBTransaction(); + Application application = executeApplicationPersistenceTransaction(applicationDTO); + ConnectionManagerUtil.commitDBTransaction(); + return application; + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while adding application with the name " + applicationDTO.getName() + " to database "; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public Application executeApplicationPersistenceTransaction(ApplicationDTO applicationDTO) throws + ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + ApplicationReleaseDTO applicationReleaseDTO = null; + if (applicationDTO.getApplicationReleaseDTOs().size() > 0) { + applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0); + } + try { // Insert to application table int appId = this.applicationDAO.createApplication(applicationDTO, tenantId); if (appId == -1) { - log.error("Application data storing is Failed."); - ConnectionManagerUtil.rollbackDBTransaction(); - deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()), - tenantId); - return null; + if (applicationReleaseDTO != null) { + deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()), + tenantId); + } + String msg = "Application data storing is Failed."; + log.error(msg); + throw new ApplicationManagementDAOException(msg); } else { if (log.isDebugEnabled()) { log.debug("New ApplicationDTO entry added to AP_APP table. App Id:" + appId); } //add application categories - List categoryIds = applicationDAO.getCategoryIdsForCategoryNames(categories, tenantId); + List categoryIds = applicationDAO.getCategoryIdsForCategoryNames(applicationDTO.getAppCategories(), tenantId); this.applicationDAO.addCategoryMapping(categoryIds, appId, tenantId); //adding application unrestricted roles - if (unrestrictedRoles != null && !unrestrictedRoles.isEmpty()) { - this.visibilityDAO.addUnrestrictedRoles(unrestrictedRoles, appId, tenantId); + if (applicationDTO.getUnrestrictedRoles() != null && !applicationDTO.getUnrestrictedRoles().isEmpty()) { + this.visibilityDAO.addUnrestrictedRoles(applicationDTO.getUnrestrictedRoles(), appId, tenantId); if (log.isDebugEnabled()) { log.debug("New restricted roles to app ID mapping added to AP_UNRESTRICTED_ROLE table." + " App Id:" + appId); @@ -908,7 +1012,7 @@ ApplicationManagerImpl implements ApplicationManager { } //adding application tags - if (tags != null && !tags.isEmpty()) { + if (applicationDTO.getTags() != null && !applicationDTO.getTags().isEmpty()) { List registeredTags = applicationDAO.getAllTags(tenantId); List registeredTagNames = new ArrayList<>(); List tagIds = new ArrayList<>(); @@ -916,16 +1020,16 @@ ApplicationManagerImpl implements ApplicationManager { for (TagDTO tagDTO : registeredTags) { registeredTagNames.add(tagDTO.getTagName()); } - List newTags = getDifference(tags, registeredTagNames); + List newTags = getDifference(applicationDTO.getTags(), registeredTagNames); if (!newTags.isEmpty()) { this.applicationDAO.addTags(newTags, tenantId); if (log.isDebugEnabled()) { log.debug("New tags entry added to AP_APP_TAG table. App Id:" + appId); } - tagIds = this.applicationDAO.getTagIdsForTagNames(tags, tenantId); + tagIds = this.applicationDAO.getTagIdsForTagNames(applicationDTO.getTags(), tenantId); } else { for (TagDTO tagDTO : registeredTags) { - for (String tagName : tags) { + for (String tagName : applicationDTO.getTags()) { if (tagName.equals(tagDTO.getTagName())) { tagIds.add(tagDTO.getId()); break; @@ -939,25 +1043,26 @@ ApplicationManagerImpl implements ApplicationManager { if (log.isDebugEnabled()) { log.debug("Creating a new release. App Id:" + appId); } - String initialLifecycleState = lifecycleStateManager.getInitialState(); - applicationReleaseDTO.setCurrentState(initialLifecycleState); - applicationReleaseDTO = this.applicationReleaseDAO - .createRelease(applicationReleaseDTO, appId, tenantId); - LifecycleState lifecycleState = getLifecycleStateInstance(initialLifecycleState, initialLifecycleState); - this.lifecycleStateDAO.addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); - applicationReleaseEntities.add(applicationReleaseDTO); + List applicationReleaseEntities = new ArrayList<>(); + if (applicationReleaseDTO != null) { + String initialLifecycleState = lifecycleStateManager.getInitialState(); + applicationReleaseDTO.setCurrentState(initialLifecycleState); + applicationReleaseDTO = this.applicationReleaseDAO + .createRelease(applicationReleaseDTO, appId, tenantId); + LifecycleState lifecycleState = getLifecycleStateInstance(initialLifecycleState, initialLifecycleState); + this.lifecycleStateDAO.addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId); + applicationReleaseEntities.add(applicationReleaseDTO); + } + applicationDTO.setId(appId); applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); - Application application = APIUtil.appDtoToAppResponse(applicationDTO); - ConnectionManagerUtil.commitDBTransaction(); - return application; + return APIUtil.appDtoToAppResponse(applicationDTO); } } catch (LifeCycleManagementDAOException e) { - ConnectionManagerUtil.rollbackDBTransaction(); String msg = "Error occurred while adding lifecycle state. application name: " + applicationDTO.getName() + "."; log.error(msg, e); try { - applicationStorageManager.deleteAllApplicationReleaseArtifacts( + APIUtil.getApplicationStorageManager().deleteAllApplicationReleaseArtifacts( Collections.singletonList(applicationReleaseDTO.getAppHashValue()), tenantId); } catch (ApplicationStorageManagementException ex) { String errorLog = @@ -968,73 +1073,59 @@ ApplicationManagerImpl implements ApplicationManager { } throw new ApplicationManagementException(msg, e); } catch (ApplicationManagementDAOException e) { - ConnectionManagerUtil.rollbackDBTransaction(); String msg = "Error occurred while adding application or application release. application name: " + applicationDTO.getName() + "."; log.error(msg, e); deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()), tenantId); throw new ApplicationManagementException(msg, e); } catch (LifecycleManagementException e) { - ConnectionManagerUtil.rollbackDBTransaction(); String msg = "Error occurred when getting initial lifecycle state. application name: " + applicationDTO.getName() + "."; log.error(msg, e); deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()), tenantId); throw new ApplicationManagementException(msg, e); - } catch (DBConnectionException e) { - String msg = "Error occurred while getting database connection."; - log.error(msg, e); - throw new ApplicationManagementException(msg, e); } catch (VisibilityManagementDAOException e) { - ConnectionManagerUtil.rollbackDBTransaction(); String msg = "Error occurred while adding unrestricted roles. application name: " + applicationDTO.getName() + "."; log.error(msg, e); deleteApplicationArtifacts(Collections.singletonList(applicationReleaseDTO.getAppHashValue()), tenantId); throw new ApplicationManagementException(msg, e); - } catch (TransactionManagementException e) { - String msg = "Error occurred while disabling AutoCommit."; - log.error(msg, e); - throw new ApplicationManagementException(msg, e); - } finally { - ConnectionManagerUtil.closeDBConnection(); } } @Override - public ApplicationRelease createEntAppRelease(int applicationId, EntAppReleaseWrapper entAppReleaseWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + public ApplicationRelease createRelease(ApplicationDTO applicationDTO, ApplicationReleaseDTO applicationReleaseDTO, + ApplicationType type) + throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); if (log.isDebugEnabled()) { - log.debug("Application release creating request is received for the application id: " + applicationId); + log.debug("Application release creating request is received for the application id: " + applicationDTO.getId()); } - ApplicationDTO applicationDTO = getApplication(applicationId); - if (!ApplicationType.ENTERPRISE.toString().equals(applicationDTO.getType())) { - String msg = "It is possible to add new application release for " + ApplicationType.ENTERPRISE.toString() + if (!type.toString().equals(applicationDTO.getType())) { + String msg = "It is possible to add new application release for " + type + " app type. But you are requesting to add new application release for " + applicationDTO.getType() + " app type."; log.error(msg); throw new BadRequestException(msg); } - DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); - if (isInvalidOsVersionRange(entAppReleaseWrapper.getSupportedOsVersions(), deviceType.getName())) { - String msg = "You are trying to add application release which has invalid or unsupported OS versions in " - + "the supportedOsVersions section. Hence, please re-evaluate the request payload."; - log.error(msg); - throw new BadRequestException(msg); + + if (!type.equals(ApplicationType.ENTERPRISE)) { + int applicationReleaseCount = applicationDTO.getApplicationReleaseDTOs().size(); + if (applicationReleaseCount > 0) { + String msg = "Application type of " + applicationDTO.getType() + " can only have one release"; + log.error(msg); + throw new BadRequestException(msg); + } } - ApplicationReleaseDTO applicationReleaseDTO = uploadEntAppReleaseArtifacts( - APIUtil.releaseWrapperToReleaseDTO(entAppReleaseWrapper), applicationArtifact, deviceType.getName(), - tenantId, true); try { ConnectionManagerUtil.beginDBTransaction(); - String initialstate = lifecycleStateManager.getInitialState(); - applicationReleaseDTO.setCurrentState(initialstate); - LifecycleState lifecycleState = getLifecycleStateInstance(initialstate, initialstate); + String initialState = lifecycleStateManager.getInitialState(); + applicationReleaseDTO.setCurrentState(initialState); + LifecycleState lifecycleState = getLifecycleStateInstance(initialState, initialState); applicationReleaseDTO = this.applicationReleaseDAO .createRelease(applicationReleaseDTO, applicationDTO.getId(), tenantId); this.lifecycleStateDAO @@ -1044,23 +1135,23 @@ ApplicationManagerImpl implements ApplicationManager { return applicationRelease; } catch (TransactionManagementException e) { String msg = "Error occurred while staring application release creating transaction for application Id: " - + applicationId; + + applicationDTO.getId(); log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (DBConnectionException e) { String msg = "Error occurred while adding application release into IoTS app management ApplicationDTO id of" - + " the application release: " + applicationId; + + " the application release: " + applicationDTO.getId(); log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (LifeCycleManagementDAOException e) { ConnectionManagerUtil.rollbackDBTransaction(); String msg = "Error occurred while adding new application release lifecycle state to the application" - + " release: " + applicationId; + + " release: " + applicationDTO.getId(); log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (ApplicationManagementDAOException e) { ConnectionManagerUtil.rollbackDBTransaction(); - String msg = "Error occurred while adding new application release for application " + applicationId; + String msg = "Error occurred while adding new application release for application " + applicationDTO.getId(); log.error(msg, e); throw new ApplicationManagementException(msg, e); } finally { @@ -1075,7 +1166,8 @@ ApplicationManagerImpl implements ApplicationManager { * @return {@link ApplicationDTO} * @throws ApplicationManagementException if error occurred application data from the databse. */ - private ApplicationDTO getApplication(int applicationId) throws ApplicationManagementException { + @Override + public ApplicationDTO getApplication(int applicationId) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { ConnectionManagerUtil.openDBConnection(); @@ -1112,7 +1204,7 @@ ApplicationManagerImpl implements ApplicationManager { * @throws ApplicationManagementException if error occurred while uploading artifacts into file system. */ private ApplicationReleaseDTO uploadEntAppReleaseArtifacts(ApplicationReleaseDTO releaseDTO, - ApplicationArtifact applicationArtifact, String deviceTypeName, int tenantId, boolean isNewRelease) + ApplicationArtifact applicationArtifact, String deviceTypeName, int tenantId, boolean isNewRelease) throws ApplicationManagementException { try { ApplicationReleaseDTO applicationReleaseDTO = addApplicationReleaseArtifacts(deviceTypeName, releaseDTO, @@ -1460,6 +1552,7 @@ ApplicationManagerImpl implements ApplicationManager { this.applicationDAO.deleteApplicationTags(applicationDTO.getId(), tenantId); this.applicationDAO.deleteAppCategories(applicationDTO.getId(), tenantId); this.visibilityDAO.deleteAppUnrestrictedRoles(applicationDTO.getId(), tenantId); + this.spApplicationDAO.deleteApplicationFromServiceProviders(applicationDTO.getId(), tenantId); this.applicationDAO.deleteApplication(applicationDTO.getId(), tenantId); APIUtil.getApplicationStorageManager().deleteAllApplicationReleaseArtifacts(deletingAppHashVals, tenantId); ConnectionManagerUtil.commitDBTransaction(); @@ -1683,7 +1776,7 @@ ApplicationManagerImpl implements ApplicationManager { @Override public void updateApplicationArtifact(String deviceType, String releaseUuid, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); boolean isValidDeviceType = false; List deviceTypes; @@ -1749,7 +1842,7 @@ ApplicationManagerImpl implements ApplicationManager { throw new ApplicationManagementException(msg, e); } catch (TransactionManagementException e) { String msg = "Error occured while starting the transaction to update application release artifact which has " - + "application uuid " + releaseUuid + "."; + + "application uuid " + releaseUuid + "."; log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (DBConnectionException e) { @@ -1787,7 +1880,7 @@ ApplicationManagerImpl implements ApplicationManager { return this.lifecycleStateDAO.getLifecycleStates(applicationReleaseDTO.getId(), tenantId); } catch (DBConnectionException e) { String msg = "Error occurred while obtaining the database connection to get lifecycle state change flow for " - + "application release which has UUID: " + releaseUuid; + + "application release which has UUID: " + releaseUuid; log.error(msg, e); throw new ApplicationManagementException(msg, e); } catch (LifeCycleManagementDAOException e) { @@ -2068,8 +2161,8 @@ ApplicationManagerImpl implements ApplicationManager { if (!getDifference(updatingAppCategries, allCategoryName).isEmpty()){ String msg = "Application update request contains invalid category names. Hence please verify the " + "request payload"; - log.error(msg); - throw new BadRequestException(msg); + log.error(msg); + throw new BadRequestException(msg); } List addingAppCategories = getDifference(updatingAppCategries, appCategories); @@ -2672,7 +2765,7 @@ ApplicationManagerImpl implements ApplicationManager { @Override public ApplicationRelease updateEntAppRelease(String releaseUuid, EntAppReleaseWrapper entAppReleaseWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { @@ -2749,7 +2842,7 @@ ApplicationManagerImpl implements ApplicationManager { @Override public ApplicationRelease updatePubAppRelease(String releaseUuid, PublicAppReleaseWrapper publicAppReleaseWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { @@ -2818,7 +2911,7 @@ ApplicationManagerImpl implements ApplicationManager { @Override public ApplicationRelease updateWebAppRelease(String releaseUuid, WebAppReleaseWrapper webAppReleaseWrapper, - ApplicationArtifact applicationArtifact) throws ApplicationManagementException { + ApplicationArtifact applicationArtifact) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); try { @@ -2883,7 +2976,7 @@ ApplicationManagerImpl implements ApplicationManager { @Override public ApplicationRelease updateCustomAppRelease(String releaseUuid, - CustomAppReleaseWrapper customAppReleaseWrapper, ApplicationArtifact applicationArtifact) + CustomAppReleaseWrapper customAppReleaseWrapper, ApplicationArtifact applicationArtifact) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); ApplicationStorageManager applicationStorageManager = APIUtil.getApplicationStorageManager(); @@ -3017,7 +3110,7 @@ ApplicationManagerImpl implements ApplicationManager { * @throws ApplicationManagementException if invalid application release updating payload received. */ private void validateAppReleaseUpdating(T param, ApplicationDTO applicationDTO, - ApplicationArtifact applicationArtifact, String appType) + ApplicationArtifact applicationArtifact, String appType) throws ApplicationManagementException { if (applicationDTO == null) { String msg = "Couldn't found an application for requested UUID."; @@ -3094,8 +3187,9 @@ ApplicationManagerImpl implements ApplicationManager { } } + @Override - public void validateAppCreatingRequest(T param) throws ApplicationManagementException { + public void validateAppCreatingRequest(T param, boolean isReleaseRequired) throws ApplicationManagementException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); int deviceTypeId = -1; @@ -3133,7 +3227,7 @@ ApplicationManagerImpl implements ApplicationManager { List entAppReleaseWrappers; entAppReleaseWrappers = applicationWrapper.getEntAppReleaseWrappers(); - if (entAppReleaseWrappers == null || entAppReleaseWrappers.size() != 1) { + if (isReleaseRequired && entAppReleaseWrappers.size() != 1) { String msg = "Invalid application creating request. Application creating request must have single " + "application release. Application name:" + applicationWrapper.getName() + "."; log.error(msg); @@ -3171,7 +3265,7 @@ ApplicationManagerImpl implements ApplicationManager { List webAppReleaseWrappers; webAppReleaseWrappers = webAppWrapper.getWebAppReleaseWrappers(); - if (webAppReleaseWrappers == null || webAppReleaseWrappers.size() != 1) { + if (isReleaseRequired && webAppReleaseWrappers.size() != 1) { String msg = "Invalid web clip creating request. Web clip creating request must have single " + "web clip release. Web clip name:" + webAppWrapper.getName() + "."; log.error(msg); @@ -3208,7 +3302,7 @@ ApplicationManagerImpl implements ApplicationManager { List publicAppReleaseWrappers; publicAppReleaseWrappers = publicAppWrapper.getPublicAppReleaseWrappers(); - if (publicAppReleaseWrappers == null || publicAppReleaseWrappers.size() != 1) { + if (isReleaseRequired && publicAppReleaseWrappers.size() != 1) { String msg = "Invalid public app creating request. Request must have single release. Application name:" + publicAppWrapper.getName() + "."; log.error(msg); @@ -3245,7 +3339,7 @@ ApplicationManagerImpl implements ApplicationManager { List customAppReleaseWrappers; customAppReleaseWrappers = customAppWrapper.getCustomAppReleaseWrappers(); - if (customAppReleaseWrappers == null || customAppReleaseWrappers.size() != 1) { + if (isReleaseRequired && customAppReleaseWrappers.size() != 1) { String msg = "Invalid custom app creating request. Application creating request must have single " + "application release. Application name:" + customAppWrapper.getName() + "."; log.error(msg); @@ -3424,9 +3518,34 @@ ApplicationManagerImpl implements ApplicationManager { } } + @Override + public void validateImageArtifacts(Base64File iconFile, List screenshots) + throws RequestValidatingException { + if (iconFile == null) { + String msg = "Icon file is not found with the application release creating request."; + log.error(msg); + throw new RequestValidatingException(msg); + } + if (screenshots == null || screenshots.isEmpty()) { + String msg = "Screenshots are not found with the application release creating request."; + log.error(msg); + throw new RequestValidatingException(msg); + } + } + + @Override + public void validateBase64File(Base64File file) throws RequestValidatingException { + if (StringUtils.isEmpty(file.getBase64String())) { + throw new RequestValidatingException("Base64File in the payload doesn't contain base64 string"); + } + if (StringUtils.isEmpty(file.getName())) { + throw new RequestValidatingException("Base64File in the payload doesn't contain file name"); + } + } + @Override public void validateImageArtifacts(Attachment iconFile, Attachment bannerFile, - List attachmentList) throws RequestValidatingException { + List attachmentList) throws RequestValidatingException { if (iconFile == null) { String msg = "Icon file is not found with the application release creating request."; log.error(msg); @@ -3439,6 +3558,16 @@ ApplicationManagerImpl implements ApplicationManager { } } + @Override + public void validateBinaryArtifact(Base64File binaryFile) throws RequestValidatingException { + if (binaryFile == null) { + String msg = "Binary file is not found with the application release creating request for ENTERPRISE app " + + "creating request."; + log.error(msg); + throw new RequestValidatingException(msg); + } + } + @Override public void validateBinaryArtifact(Attachment binaryFile) throws RequestValidatingException { if (binaryFile == null) { @@ -3515,18 +3644,18 @@ ApplicationManagerImpl implements ApplicationManager { String artifactDownloadURL = APIUtil.getArtifactDownloadBaseURL() + tenantId + Constants.FORWARD_SLASH + applicationReleaseDTO.getUuid() + Constants.FORWARD_SLASH + Constants.APP_ARTIFACT + Constants.FORWARD_SLASH + - applicationReleaseDTO.getInstallerName(); + applicationReleaseDTO.getInstallerName(); String plistContent = "<!DOCTYPE plist PUBLIC "-//Apple//DTDPLIST1.0//EN" "" + - "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="" + - "1.0"><dict><key>items</key><array><dict><" + - "key>assets</key><array><dict><key>kind</key><" + - "string>software-package</string><key>url</key><string>" + - "$downloadURL</string></dict></array><key>metadata<" + - "/key><dict><key>bundle-identifier</key><string>" + - "$packageName</string><key>bundle-version</key><string>" + - "$bundleVersion</string><key>kind</key><string>" + - "software</string><key>title</key><string>$appName<" + - "/string></dict></dict></array></dict></plist>"; + "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="" + + "1.0"><dict><key>items</key><array><dict><" + + "key>assets</key><array><dict><key>kind</key><" + + "string>software-package</string><key>url</key><string>" + + "$downloadURL</string></dict></array><key>metadata<" + + "/key><dict><key>bundle-identifier</key><string>" + + "$packageName</string><key>bundle-version</key><string>" + + "$bundleVersion</string><key>kind</key><string>" + + "software</string><key>title</key><string>$appName<" + + "/string></dict></dict></array></dict></plist>"; plistContent = plistContent.replace("$downloadURL", artifactDownloadURL) .replace("$packageName", applicationReleaseDTO.getPackageName()) .replace("$bundleVersion", applicationReleaseDTO.getVersion()) diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/impl/SPApplicationManagerImpl.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/impl/SPApplicationManagerImpl.java new file mode 100644 index 00000000000..447487e0d47 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/impl/SPApplicationManagerImpl.java @@ -0,0 +1,347 @@ +package io.entgra.application.mgt.core.impl; + +import io.entgra.application.mgt.common.ApplicationArtifact; +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.common.IdentityServerList; +import io.entgra.application.mgt.common.SPApplication; +import io.entgra.application.mgt.common.dto.ApplicationDTO; +import io.entgra.application.mgt.common.exception.ApplicationManagementException; +import io.entgra.application.mgt.common.exception.DBConnectionException; +import io.entgra.application.mgt.common.exception.RequestValidatingException; +import io.entgra.application.mgt.common.exception.TransactionManagementException; +import io.entgra.application.mgt.common.response.Application; +import io.entgra.application.mgt.common.services.ApplicationManager; +import io.entgra.application.mgt.common.services.SPApplicationManager; +import io.entgra.application.mgt.common.wrapper.ApplicationWrapper; +import io.entgra.application.mgt.common.wrapper.CustomAppReleaseWrapper; +import io.entgra.application.mgt.common.wrapper.CustomAppWrapper; +import io.entgra.application.mgt.common.wrapper.EntAppReleaseWrapper; +import io.entgra.application.mgt.common.wrapper.PublicAppReleaseWrapper; +import io.entgra.application.mgt.common.wrapper.PublicAppWrapper; +import io.entgra.application.mgt.common.wrapper.WebAppReleaseWrapper; +import io.entgra.application.mgt.common.wrapper.WebAppWrapper; +import io.entgra.application.mgt.core.dao.ApplicationDAO; +import io.entgra.application.mgt.core.dao.SPApplicationDAO; +import io.entgra.application.mgt.core.dao.VisibilityDAO; +import io.entgra.application.mgt.core.dao.common.ApplicationManagementDAOFactory; +import io.entgra.application.mgt.core.exception.ApplicationManagementDAOException; +import io.entgra.application.mgt.core.exception.BadRequestException; +import io.entgra.application.mgt.core.internal.DataHolder; +import io.entgra.application.mgt.core.lifecycle.LifecycleStateManager; +import io.entgra.application.mgt.core.util.APIUtil; +import io.entgra.application.mgt.core.util.ApplicationManagementUtil; +import io.entgra.application.mgt.core.util.ConnectionManagerUtil; +import io.entgra.application.mgt.core.util.Constants; +import io.entgra.application.mgt.core.util.SPApplicationManagementUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; + +import java.util.ArrayList; +import java.util.List; + +public class SPApplicationManagerImpl implements SPApplicationManager { + + private static final Log log = LogFactory.getLog(SPApplicationManagerImpl.class); + private ApplicationDAO applicationDAO; + private SPApplicationDAO spApplicationDAO; + private VisibilityDAO visibilityDAO; + private final LifecycleStateManager lifecycleStateManager; + + public SPApplicationManagerImpl() { + initDataAccessObjects(); + lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager(); + } + + private void initDataAccessObjects() { + this.applicationDAO = ApplicationManagementDAOFactory.getApplicationDAO(); + this.visibilityDAO = ApplicationManagementDAOFactory.getVisibilityDAO(); + this.spApplicationDAO = ApplicationManagementDAOFactory.getSPApplicationDAO(); + } + + public void addExistingApps(int identityServerId, List applications) throws ApplicationManagementException { + for (SPApplication application : applications) { + List existingApplications = getSPApplications(identityServerId, application.getId()); + application.setExistingApplications(existingApplications); + } + } + + @Override + public IdentityServer getIdentityServer(int identityServerId) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + try { + ConnectionManagerUtil.openDBConnection(); + return spApplicationDAO.getIdentityServerById(identityServerId, tenantId); + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection to get identity server with the id: " + identityServerId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = + "DAO exception while getting identity server with the id " + identityServerId ; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public IdentityServerList getIdentityServers() throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + try { + ConnectionManagerUtil.openDBConnection(); + IdentityServerList identityServerList = new IdentityServerList(); + identityServerList.setIdentityServers(spApplicationDAO.getIdentityServers(tenantId)); + return identityServerList; + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection to get identity servers"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = + "DAO exception while getting identity servers"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public List getSPApplications(int identityServerId, String spUID) throws + ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + List applications = new ArrayList<>(); + + try { + ConnectionManagerUtil.openDBConnection(); + List appDTOs = spApplicationDAO.getSPApplications(identityServerId, spUID, tenantId); + for (ApplicationDTO applicationDTO : appDTOs) { + if (lifecycleStateManager.getEndState().equals(applicationDTO.getStatus())) { + continue; + } + boolean isHideableApp = applicationManager.isHideableApp(applicationDTO.getApplicationReleaseDTOs()); + boolean isDeletableApp = applicationManager.isDeletableApp(applicationDTO.getApplicationReleaseDTOs()); + + //Set application categories, tags and unrestricted roles to the application DTO. + applicationDTO + .setUnrestrictedRoles(visibilityDAO.getUnrestrictedRoles(applicationDTO.getId(), tenantId)); + applicationDTO.setAppCategories(applicationDAO.getAppCategories(applicationDTO.getId(), tenantId)); + applicationDTO.setTags(applicationDAO.getAppTags(applicationDTO.getId(), tenantId)); + + applicationDTO.setApplicationReleaseDTOs(applicationDTO.getApplicationReleaseDTOs()); + Application application = APIUtil.appDtoToAppResponse(applicationDTO); + application.setDeletableApp(isDeletableApp); + application.setHideableApp(isHideableApp); + applications.add(application); + } + + return applications; + } catch (DBConnectionException e) { + String msg = "Error occurred when getting database connection to get applications by filtering from " + + "requested filter."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementDAOException e) { + String msg = + "DAO exception while getting applications of tenant " + tenantId ; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + public void validateAttachAppsRequest(int identityServerId, List appIds) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + for (int appId : appIds) { + try { + ApplicationDTO appDTO = applicationDAO.getApplication(appId, tenantId); + if (appDTO == null) { + String msg = "Payload contains invalid an app id. " + "No app exist with the appId: " + appId + "."; + throw new BadRequestException(msg); + } + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while trying to retrieve application with the id:" + appId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + public void validateDetachAppsRequest(int identityServerId, String spId, List appIds) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + try { + ConnectionManagerUtil.openDBConnection(); + for (int id : appIds) { + try { + boolean isSPAppExist = spApplicationDAO.isSPApplicationExist(identityServerId, spId, id, tenantId); + if (!isSPAppExist) { + String msg = "No service provider app exist with the appId: " + id + " for service provider with the " + + "UID " + spId; + throw new ApplicationManagementException(msg); + } + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while checking if application exists with the id:" + id; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + public void attachSPApplications(int identityServerId, String spUID, List appIds) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + try { + ConnectionManagerUtil.beginDBTransaction(); + for (int appId : appIds) { + spApplicationDAO.attachSPApplication(identityServerId, spUID, appId, tenantId); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (ApplicationManagementDAOException e){ + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "DAO exception while getting applications of tenant " + tenantId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + + public void detachSPApplications(int identityServerId, String spUID, List appIds) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + try { + ConnectionManagerUtil.beginDBTransaction(); + for (int id : appIds) { + spApplicationDAO.detachSPApplication(identityServerId, spUID, id, tenantId); + } + ConnectionManagerUtil.commitDBTransaction(); + } catch (ApplicationManagementDAOException e){ + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = + "DAO exception while getting applications of tenant " + tenantId; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + @Override + public Application createSPApplication(T app, int identityServerId, String spId) throws ApplicationManagementException, + RequestValidatingException { + ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance(); + applicationManager.validateAppCreatingRequest(app, false); + ApplicationDTO applicationDTO = constructApplicationDTO(app); + try { + ConnectionManagerUtil.beginDBTransaction(); + Application createdApp = createSPApplication(applicationDTO); + attachCreatedSPApplication(createdApp, identityServerId, spId); + ConnectionManagerUtil.commitDBTransaction(); + return createdApp; + } catch (DBConnectionException e) { + String msg = "Error occurred while getting database connection."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (TransactionManagementException e) { + String msg = "Error occurred while disabling AutoCommit."; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } catch (ApplicationManagementException e) { + ConnectionManagerUtil.rollbackDBTransaction(); + String msg = "Error occurred while creating and attaching application with the name " + applicationDTO.getName() ; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + ConnectionManagerUtil.closeDBConnection(); + } + } + + private ApplicationDTO constructApplicationDTO(T app) throws ApplicationManagementException, + RequestValidatingException { + if (ApplicationManagementUtil.isReleaseAvailable(app)) { + return uploadReleaseArtifactAndConstructApplicationDTO(app); + } + return APIUtil.convertToAppDTO(app); + } + + public Application createSPApplication(ApplicationDTO applicationDTO) throws ApplicationManagementException { + if (log.isDebugEnabled()) { + log.debug("Application release create request is received. Application name: " + applicationDTO.getName() + + " Device type ID: " + applicationDTO.getDeviceTypeId()); + } + ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance(); + return applicationManager.executeApplicationPersistenceTransaction(applicationDTO); + } + + + + public void attachCreatedSPApplication(Application createdApp, int identityServerId, String spUID) throws ApplicationManagementException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + try { + spApplicationDAO.attachSPApplication(identityServerId, spUID, createdApp.getId(), tenantId); + } catch (ApplicationManagementDAOException e) { + String msg = "Error occurred while attaching application with the id " + createdApp.getId(); + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } + } + + public ApplicationDTO uploadReleaseArtifactAndConstructApplicationDTO(T app) throws ApplicationManagementException, + RequestValidatingException { + ApplicationArtifact artifact; + ApplicationDTO applicationDTO; + ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance(); + if (app instanceof ApplicationWrapper) { + ApplicationWrapper wrapper = (ApplicationWrapper) app; + EntAppReleaseWrapper releaseWrapper = wrapper.getEntAppReleaseWrappers().get(0); + applicationManager.validateReleaseCreatingRequest(releaseWrapper, wrapper.getDeviceType()); + applicationManager.validateBinaryArtifact(releaseWrapper.getBinaryFile()); + applicationManager.validateImageArtifacts(releaseWrapper.getIcon(), releaseWrapper.getScreenshots()); + artifact = ApplicationManagementUtil.constructApplicationArtifact(releaseWrapper.getIcon(), + releaseWrapper.getScreenshots(), releaseWrapper.getBinaryFile(), null); + applicationDTO = applicationManager.uploadEntAppReleaseArtifacts(wrapper, artifact); + } else if (app instanceof PublicAppWrapper) { + PublicAppWrapper wrapper = (PublicAppWrapper) app; + PublicAppReleaseWrapper releaseWrapper = wrapper.getPublicAppReleaseWrappers().get(0); + applicationManager.validateReleaseCreatingRequest(releaseWrapper, wrapper.getDeviceType()); + applicationManager.validateImageArtifacts(releaseWrapper.getIcon(), releaseWrapper.getScreenshots()); + artifact = ApplicationManagementUtil.constructApplicationArtifact(releaseWrapper.getIcon(), + releaseWrapper.getScreenshots(), null, null); + applicationDTO = applicationManager.uploadPublicAppReleaseArtifacts(wrapper, artifact); + } else if (app instanceof WebAppWrapper) { + WebAppWrapper wrapper = (WebAppWrapper) app; + WebAppReleaseWrapper releaseWrapper = wrapper.getWebAppReleaseWrappers().get(0); + applicationManager.validateReleaseCreatingRequest(releaseWrapper, Constants.ANY); + applicationManager.validateImageArtifacts(releaseWrapper.getIcon(), releaseWrapper.getScreenshots()); + artifact = ApplicationManagementUtil.constructApplicationArtifact(releaseWrapper.getIcon(), + releaseWrapper.getScreenshots(), null, null); + applicationDTO = applicationManager.uploadWebAppReleaseArtifacts(wrapper, artifact); + } else if (app instanceof CustomAppWrapper) { + CustomAppWrapper wrapper = (CustomAppWrapper) app; + CustomAppReleaseWrapper releaseWrapper = wrapper.getCustomAppReleaseWrappers().get(0); + applicationManager.validateReleaseCreatingRequest(releaseWrapper, wrapper.getDeviceType()); + applicationManager.validateBinaryArtifact(releaseWrapper.getBinaryFile()); + applicationManager.validateImageArtifacts(releaseWrapper.getIcon(), releaseWrapper.getScreenshots()); + artifact = ApplicationManagementUtil.constructApplicationArtifact(releaseWrapper.getIcon(), + releaseWrapper.getScreenshots(), releaseWrapper.getBinaryFile(), null); + applicationDTO = applicationManager.uploadCustomAppReleaseArtifactsAndConstructAppDTO(wrapper, artifact); + } else { + String msg = "Invalid payload found with the request. Hence verify the request payload object."; + log.error(msg); + throw new ApplicationManagementException(msg); + } + return applicationDTO; + } +} diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/internal/ApplicationManagementServiceComponent.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/internal/ApplicationManagementServiceComponent.java index e56f73e1cb8..be8cd12d460 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/internal/ApplicationManagementServiceComponent.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/internal/ApplicationManagementServiceComponent.java @@ -17,6 +17,7 @@ */ package io.entgra.application.mgt.core.internal; +import io.entgra.application.mgt.common.services.SPApplicationManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.framework.BundleContext; @@ -88,6 +89,10 @@ public class ApplicationManagementServiceComponent { DataHolder.getInstance().setLifecycleStateManger(lifecycleStateManager); bundleContext.registerService(LifecycleStateManager.class.getName(), lifecycleStateManager, null); + SPApplicationManager SPApplicationManager = ApplicationManagementUtil.getSPApplicationManagerInstance(); + DataHolder.getInstance().setISApplicationManager(SPApplicationManager); + bundleContext.registerService(SPApplicationManager.class.getName(), SPApplicationManager, null); + ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance(); applicationManager .addApplicationCategories(ConfigurationManager.getInstance().getConfiguration().getAppCategories()); diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/internal/DataHolder.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/internal/DataHolder.java index 3c675db85a7..f7bc6e1d8c1 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/internal/DataHolder.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/internal/DataHolder.java @@ -20,6 +20,7 @@ package io.entgra.application.mgt.core.internal; import io.entgra.application.mgt.common.services.ApplicationManager; import io.entgra.application.mgt.common.services.ApplicationStorageManager; import io.entgra.application.mgt.common.services.AppmDataHandler; +import io.entgra.application.mgt.common.services.SPApplicationManager; import io.entgra.application.mgt.common.services.ReviewManager; import io.entgra.application.mgt.common.services.SubscriptionManager; import io.entgra.application.mgt.core.lifecycle.LifecycleStateManager; @@ -36,6 +37,8 @@ public class DataHolder { private RealmService realmService; + private SPApplicationManager SPApplicationManager; + private ApplicationManager applicationManager; private ReviewManager reviewManager; @@ -131,4 +134,12 @@ public class DataHolder { public void setTaskService(TaskService taskService) { this.taskService = taskService; } + + public SPApplicationManager getISApplicationManager() { + return SPApplicationManager; + } + + public void setISApplicationManager(SPApplicationManager SPApplicationManager) { + this.SPApplicationManager = SPApplicationManager; + } } diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/APIUtil.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/APIUtil.java index 0afcc85ab50..cb4eb7edffc 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/APIUtil.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/APIUtil.java @@ -59,12 +59,31 @@ public class APIUtil { private static Log log = LogFactory.getLog(APIUtil.class); + private static volatile SPApplicationManager SPApplicationManager; private static volatile ApplicationManager applicationManager; private static volatile ApplicationStorageManager applicationStorageManager; private static volatile SubscriptionManager subscriptionManager; private static volatile ReviewManager reviewManager; private static volatile AppmDataHandler appmDataHandler; + public static SPApplicationManager getSPApplicationManager() { + if (SPApplicationManager == null) { + synchronized (APIUtil.class) { + if (SPApplicationManager == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + SPApplicationManager = + (SPApplicationManager) ctx.getOSGiService(SPApplicationManager.class, null); + if (SPApplicationManager == null) { + String msg = "ApplicationDTO Manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return SPApplicationManager; + } + public static ApplicationManager getApplicationManager() { if (applicationManager == null) { synchronized (APIUtil.class) { @@ -231,6 +250,7 @@ public class APIUtil { public static ApplicationDTO convertToAppDTO(T param) throws BadRequestException, UnexpectedServerErrorException { ApplicationDTO applicationDTO = new ApplicationDTO(); + List applicationReleaseEntities; if (param instanceof ApplicationWrapper){ ApplicationWrapper applicationWrapper = (ApplicationWrapper) param; @@ -244,7 +264,7 @@ public class APIUtil { applicationDTO.setTags(applicationWrapper.getTags()); applicationDTO.setUnrestrictedRoles(applicationWrapper.getUnrestrictedRoles()); applicationDTO.setDeviceTypeId(deviceType.getId()); - List applicationReleaseEntities = applicationWrapper.getEntAppReleaseWrappers() + applicationReleaseEntities = applicationWrapper.getEntAppReleaseWrappers() .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); } else if (param instanceof WebAppWrapper){ @@ -257,7 +277,7 @@ public class APIUtil { applicationDTO.setType(webAppWrapper.getType()); applicationDTO.setTags(webAppWrapper.getTags()); applicationDTO.setUnrestrictedRoles(webAppWrapper.getUnrestrictedRoles()); - List applicationReleaseEntities = webAppWrapper.getWebAppReleaseWrappers() + applicationReleaseEntities = webAppWrapper.getWebAppReleaseWrappers() .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); } else if (param instanceof PublicAppWrapper) { @@ -272,7 +292,7 @@ public class APIUtil { applicationDTO.setTags(publicAppWrapper.getTags()); applicationDTO.setUnrestrictedRoles(publicAppWrapper.getUnrestrictedRoles()); applicationDTO.setDeviceTypeId(deviceType.getId()); - List applicationReleaseEntities = publicAppWrapper.getPublicAppReleaseWrappers() + applicationReleaseEntities = publicAppWrapper.getPublicAppReleaseWrappers() .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); } else if (param instanceof CustomAppWrapper){ @@ -287,7 +307,7 @@ public class APIUtil { applicationDTO.setTags(customAppWrapper.getTags()); applicationDTO.setUnrestrictedRoles(customAppWrapper.getUnrestrictedRoles()); applicationDTO.setDeviceTypeId(deviceType.getId()); - List applicationReleaseEntities = customAppWrapper.getCustomAppReleaseWrappers() + applicationReleaseEntities = customAppWrapper.getCustomAppReleaseWrappers() .stream().map(APIUtil::releaseWrapperToReleaseDTO).collect(Collectors.toList()); applicationDTO.setApplicationReleaseDTOs(applicationReleaseEntities); } @@ -362,7 +382,9 @@ public class APIUtil { application.setTags(applicationDTO.getTags()); application.setUnrestrictedRoles(applicationDTO.getUnrestrictedRoles()); application.setRating(applicationDTO.getAppRating()); - application.setInstallerName(applicationDTO.getApplicationReleaseDTOs().get(0).getInstallerName()); + if (applicationDTO.getApplicationReleaseDTOs() != null && !applicationDTO.getApplicationReleaseDTOs().isEmpty()) { + application.setInstallerName(applicationDTO.getApplicationReleaseDTOs().get(0).getInstallerName()); + } List applicationReleases = new ArrayList<>(); if (ApplicationType.PUBLIC.toString().equals(applicationDTO.getType()) && application.getCategories() .contains("GooglePlaySyncedApp")) { diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/ApplicationManagementUtil.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/ApplicationManagementUtil.java index 11d8adb2ce4..ad5cabf8a40 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/ApplicationManagementUtil.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/ApplicationManagementUtil.java @@ -17,6 +17,23 @@ */ package io.entgra.application.mgt.core.util; +import io.entgra.application.mgt.common.ApplicationArtifact; +import io.entgra.application.mgt.common.ApplicationSubscriptionType; +import io.entgra.application.mgt.common.ApplicationType; +import io.entgra.application.mgt.common.Base64File; +import io.entgra.application.mgt.common.FileDataHolder; +import io.entgra.application.mgt.common.exception.ApplicationManagementException; +import io.entgra.application.mgt.common.exception.RequestValidatingException; +import io.entgra.application.mgt.common.services.SPApplicationManager; +import io.entgra.application.mgt.common.wrapper.ApplicationWrapper; +import io.entgra.application.mgt.common.wrapper.CustomAppReleaseWrapper; +import io.entgra.application.mgt.common.wrapper.CustomAppWrapper; +import io.entgra.application.mgt.common.wrapper.EntAppReleaseWrapper; +import io.entgra.application.mgt.common.wrapper.PublicAppReleaseWrapper; +import io.entgra.application.mgt.common.wrapper.PublicAppWrapper; +import io.entgra.application.mgt.common.wrapper.WebAppReleaseWrapper; +import io.entgra.application.mgt.common.wrapper.WebAppWrapper; +import io.entgra.application.mgt.core.exception.BadRequestException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import io.entgra.application.mgt.common.exception.InvalidConfigurationException; @@ -27,8 +44,16 @@ import io.entgra.application.mgt.common.services.SubscriptionManager; import io.entgra.application.mgt.core.config.ConfigurationManager; import io.entgra.application.mgt.core.config.Extension; import io.entgra.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.mgt.core.common.util.FileUtil; +import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; /** * This DAOUtil class is responsible for making sure single instance of each Extension Manager is used throughout for @@ -38,6 +63,77 @@ public class ApplicationManagementUtil { private static Log log = LogFactory.getLog(ApplicationManagementUtil.class); + public static ApplicationArtifact constructApplicationArtifact(Base64File iconBase64, List screenshotsBase64, + Base64File binaryFileBase64, Base64File bannerFileBase64) + throws BadRequestException { + ApplicationArtifact applicationArtifact = new ApplicationArtifact(); + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + if (binaryFileBase64 != null) { + try { + applicationManager.validateBase64File(binaryFileBase64); + } catch (RequestValidatingException e) { + String msg = "Invalid base64 binary file payload found"; + log.error(msg, e); + throw new BadRequestException(msg, e); + } + FileDataHolder binaryFile = base64FileToFileDataHolder(binaryFileBase64); + applicationArtifact.setInstallerName(binaryFile.getName()); + applicationArtifact.setInstallerStream(binaryFile.getFile()); + } + if (iconBase64 != null) { + try { + applicationManager.validateBase64File(iconBase64); + } catch (RequestValidatingException e) { + String msg = "Invalid base64 icon file payload found"; + log.error(msg, e); + throw new BadRequestException(msg, e); + } + FileDataHolder iconFile = base64FileToFileDataHolder(iconBase64); + applicationArtifact.setIconName(iconFile.getName()); + applicationArtifact.setIconStream(iconFile.getFile()); + } + if (bannerFileBase64 != null) { + try { + applicationManager.validateBase64File(bannerFileBase64); + } catch (RequestValidatingException e) { + String msg = "Invalid base64 banner file payload found"; + log.error(msg, e); + throw new BadRequestException(msg, e); + } + FileDataHolder bannerFile = base64FileToFileDataHolder(bannerFileBase64); + applicationArtifact.setBannerName(bannerFile.getName()); + applicationArtifact.setBannerStream(bannerFile.getFile()); + } + + if (screenshotsBase64 != null) { + Map screenshotData = new TreeMap<>(); + for (Base64File screenshot : screenshotsBase64) { + try { + applicationManager.validateBase64File(screenshot); + } catch (RequestValidatingException e) { + String msg = "Invalid base64 screenshot file payload found"; + log.error(msg, e); + throw new BadRequestException(msg, e); + } + FileDataHolder screenshotFile = base64FileToFileDataHolder(screenshot); + screenshotData.put(screenshotFile.getName(), screenshotFile.getFile()); + } + applicationArtifact.setScreenshots(screenshotData); + } + return applicationArtifact; + } + + public static FileDataHolder base64FileToFileDataHolder(Base64File base64File) { + InputStream stream = FileUtil.base64ToInputStream(base64File.getBase64String()); + return new FileDataHolder(base64File.getName(), stream); + } + + public static SPApplicationManager getSPApplicationManagerInstance() throws InvalidConfigurationException { + ConfigurationManager configurationManager = ConfigurationManager.getInstance(); + Extension extension = configurationManager.getExtension(Extension.Name.SPApplicationManager); + return getInstance(extension, SPApplicationManager.class); + } + public static ApplicationManager getApplicationManagerInstance() throws InvalidConfigurationException { ConfigurationManager configurationManager = ConfigurationManager.getInstance(); Extension extension = configurationManager.getExtension(Extension.Name.ApplicationManager); @@ -69,7 +165,27 @@ public class ApplicationManagementUtil { return getInstance(extension, LifecycleStateManager.class); } - private static T getInstance(Extension extension, Class cls) throws InvalidConfigurationException { + public static boolean isReleaseAvailable(T appWrapper) { + if (appWrapper instanceof ApplicationWrapper) { + List entAppReleaseWrappers = ((ApplicationWrapper) appWrapper).getEntAppReleaseWrappers(); + return entAppReleaseWrappers != null && !entAppReleaseWrappers.isEmpty(); + } + if (appWrapper instanceof PublicAppWrapper) { + List publicAppReleaseWrappers = ((PublicAppWrapper) appWrapper).getPublicAppReleaseWrappers(); + return publicAppReleaseWrappers != null && !publicAppReleaseWrappers.isEmpty(); + } + if (appWrapper instanceof WebAppWrapper) { + List webAppReleaseWrappers = ((WebAppWrapper) appWrapper).getWebAppReleaseWrappers(); + return webAppReleaseWrappers != null && !webAppReleaseWrappers.isEmpty(); + } + if (appWrapper instanceof CustomAppWrapper) { + List customAppReleaseWrappers = ((CustomAppWrapper) appWrapper).getCustomAppReleaseWrappers(); + return customAppReleaseWrappers != null && !((CustomAppWrapper) appWrapper).getCustomAppReleaseWrappers().isEmpty(); + } + throw new IllegalArgumentException("Provided bean does not belong to an Application Wrapper"); + } + + public static T getInstance(Extension extension, Class cls) throws InvalidConfigurationException { try { Class theClass = Class.forName(extension.getClassName()); if (extension.getParameters() != null && extension.getParameters().size() > 0) { diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/Constants.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/Constants.java index 3302ddd25d8..03f94ef1d0f 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/Constants.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/Constants.java @@ -35,6 +35,8 @@ public class Constants { public static final String DEFAULT_CONFIG_FILE_LOCATION = CarbonUtils.getCarbonConfigDirPath() + File.separator + Constants.APPLICATION_CONFIG_XML_FILE; public static final String DEFAULT_VERSION = "1.0.0"; + public static final String SCREENSHOT_NAME = "screenshot"; + public static final String ICON_NAME = "icon"; public static final String PAYLOAD = "Payload"; public static final String PLIST_NAME = "Info.plist"; public static final String CF_BUNDLE_VERSION = "CFBundleVersion"; @@ -45,6 +47,15 @@ public class Constants { public static final String HTTPS_PROTOCOL = "https"; public static final String HTTP_PROTOCOL = "http"; + public static final String LIMIT_QUERY_PARAM = "limit"; + public static final String OFFSET_QUERY_PARAM = "offset"; + public static final String IS_APPS_API_CONTEXT_PATH = "identity-server-applications"; + public static final String IS_APPS_API_BASE_PATH = "identity-server-applications"; + public static final Double IS_APP_DEFAULT_PRICE = 0.0; + public static final String SP_APP_CATEGORY = "SPApp"; + public static final String IS_APP_RELEASE_TYPE = "stable"; + public static final String IS_APP_DEFAULT_PAYMENT_CURRENCY = "$"; + public static final String IS_APP_DEFAULT_VERSION = "1.0"; public static final String FORWARD_SLASH = "/"; public static final String ANY = "ANY"; public static final String DEFAULT_PCK_NAME = "default.app.com"; diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/DAOUtil.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/DAOUtil.java index 6acfa182a1d..dc276ddf257 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/DAOUtil.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/DAOUtil.java @@ -19,6 +19,7 @@ package io.entgra.application.mgt.core.util; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import io.entgra.application.mgt.common.IdentityServer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.JSONException; @@ -38,10 +39,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -86,10 +84,16 @@ public class DAOUtil { application.setAppRating(rs.getDouble("APP_RATING")); application.setDeviceTypeId(rs.getInt("APP_DEVICE_TYPE_ID")); application.setPackageName(rs.getString("PACKAGE_NAME")); - application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs)); + ApplicationReleaseDTO releaseDTO = constructAppReleaseDTO(rs); + if (releaseDTO != null) { + application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs)); + } } else { if (application != null && application.getApplicationReleaseDTOs() != null) { - application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs)); + ApplicationReleaseDTO releaseDTO = constructAppReleaseDTO(rs); + if (releaseDTO != null) { + application.getApplicationReleaseDTOs().add(constructAppReleaseDTO(rs)); + } } } hasNext = rs.next(); @@ -139,26 +143,76 @@ public class DAOUtil { */ public static ApplicationReleaseDTO constructAppReleaseDTO(ResultSet rs) throws SQLException { ApplicationReleaseDTO appRelease = new ApplicationReleaseDTO(); - appRelease.setId(rs.getInt("RELEASE_ID")); - appRelease.setDescription(rs.getString("RELEASE_DESCRIPTION")); - appRelease.setUuid(rs.getString("RELEASE_UUID")); - appRelease.setReleaseType(rs.getString("RELEASE_TYPE")); - appRelease.setVersion(rs.getString("RELEASE_VERSION")); - appRelease.setInstallerName(rs.getString("AP_RELEASE_STORED_LOC")); - appRelease.setIconName(rs.getString("AP_RELEASE_ICON_LOC")); - appRelease.setBannerName(rs.getString("AP_RELEASE_BANNER_LOC")); - appRelease.setScreenshotName1(rs.getString("AP_RELEASE_SC1")); - appRelease.setScreenshotName2(rs.getString("AP_RELEASE_SC2")); - appRelease.setScreenshotName3(rs.getString("AP_RELEASE_SC3")); - appRelease.setAppHashValue(rs.getString("RELEASE_HASH_VALUE")); - appRelease.setPrice(rs.getDouble("RELEASE_PRICE")); - appRelease.setMetaData(rs.getString("RELEASE_META_INFO")); - appRelease.setPackageName(rs.getString("PACKAGE_NAME")); - appRelease.setSupportedOsVersions(rs.getString("RELEASE_SUP_OS_VERSIONS")); - appRelease.setRating(rs.getDouble("RELEASE_RATING")); - appRelease.setCurrentState(rs.getString("RELEASE_CURRENT_STATE")); - appRelease.setRatedUsers(rs.getInt("RATED_USER_COUNT")); - return appRelease; + if (rs.getString("RELEASE_UUID") != null) { + appRelease.setId(rs.getInt("RELEASE_ID")); + appRelease.setDescription(rs.getString("RELEASE_DESCRIPTION")); + appRelease.setUuid(rs.getString("RELEASE_UUID")); + appRelease.setReleaseType(rs.getString("RELEASE_TYPE")); + appRelease.setVersion(rs.getString("RELEASE_VERSION")); + appRelease.setInstallerName(rs.getString("AP_RELEASE_STORED_LOC")); + appRelease.setIconName(rs.getString("AP_RELEASE_ICON_LOC")); + appRelease.setBannerName(rs.getString("AP_RELEASE_BANNER_LOC")); + appRelease.setScreenshotName1(rs.getString("AP_RELEASE_SC1")); + appRelease.setScreenshotName2(rs.getString("AP_RELEASE_SC2")); + appRelease.setScreenshotName3(rs.getString("AP_RELEASE_SC3")); + appRelease.setAppHashValue(rs.getString("RELEASE_HASH_VALUE")); + appRelease.setPrice(rs.getDouble("RELEASE_PRICE")); + appRelease.setMetaData(rs.getString("RELEASE_META_INFO")); + appRelease.setPackageName(rs.getString("PACKAGE_NAME")); + appRelease.setSupportedOsVersions(rs.getString("RELEASE_SUP_OS_VERSIONS")); + appRelease.setRating(rs.getDouble("RELEASE_RATING")); + appRelease.setCurrentState(rs.getString("RELEASE_CURRENT_STATE")); + appRelease.setRatedUsers(rs.getInt("RATED_USER_COUNT")); + return appRelease; + } + return null; + } + + /** + * To create application object from the result set retrieved from the Database. + * + * @param rs ResultSet + * @return IdentityServer that is retrieved from the Database. + * @throws SQLException SQL Exception + * @throws JSONException JSONException. + */ + public static IdentityServer loadIdentityServer(ResultSet rs) + throws SQLException, JSONException, UnexpectedServerErrorException { + List identityServers = loadIdentityServers(rs); + if (identityServers.isEmpty()) { + return null; + } + if (identityServers.size() > 1) { + String msg = "Internal server error. Found more than one identity server for requested ID"; + log.error(msg); + throw new UnexpectedServerErrorException(msg); + } + return identityServers.get(0); + } + + /** + * To create application object from the result set retrieved from the Database. + * + * @param rs ResultSet + * @return List of Applications that is retrieved from the Database. + * @throws SQLException SQL Exception + * @throws JSONException JSONException. + */ + public static List loadIdentityServers(ResultSet rs) throws SQLException, JSONException { + List identityServers = new ArrayList<>(); + while (rs.next()) { + IdentityServer identityServer = new IdentityServer(); + identityServer.setId(rs.getInt("ID")); + identityServer.setName(rs.getString("NAME")); + identityServer.setDescription(rs.getString("DESCRIPTION")); + identityServer.setUrl(rs.getString("URL")); + identityServer.setSpAppsURI(rs.getString("SP_APPS_URI")); + identityServer.setSpAppsApi(rs.getString("SP_APPS_API")); + identityServer.setUserName(rs.getString("USERNAME")); + identityServer.setPassword(rs.getString("PASSWORD")); + identityServers.add(identityServer); + } + return identityServers; } diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/SPApplicationManagementUtil.java b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/SPApplicationManagementUtil.java new file mode 100644 index 00000000000..53c11fd6f31 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.core/src/main/java/io/entgra/application/mgt/core/util/SPApplicationManagementUtil.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Entgra (pvt) Ltd. (http://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.application.mgt.core.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import java.util.ArrayList; +import java.util.List; + +/** + * This DAOUtil class is responsible for making sure single instance of each Extension Manager is used throughout for + * all the tasks. + */ +public class SPApplicationManagementUtil { + + private static Log log = LogFactory.getLog(SPApplicationManagementUtil.class); + + private static List getDefaultSPAppCategories() { + List categories = new ArrayList<>(); + categories.add(Constants.SP_APP_CATEGORY); + return categories; + } + + +} diff --git a/components/application-mgt/io.entgra.application.mgt.core/src/test/java/io/entgra/application/mgt/core/management/ApplicationManagementTest.java b/components/application-mgt/io.entgra.application.mgt.core/src/test/java/io/entgra/application/mgt/core/management/ApplicationManagementTest.java index 998e10e5b13..c781b674df9 100644 --- a/components/application-mgt/io.entgra.application.mgt.core/src/test/java/io/entgra/application/mgt/core/management/ApplicationManagementTest.java +++ b/components/application-mgt/io.entgra.application.mgt.core/src/test/java/io/entgra/application/mgt/core/management/ApplicationManagementTest.java @@ -41,7 +41,6 @@ import io.entgra.application.mgt.core.dto.ApplicationsDTO; import io.entgra.application.mgt.core.impl.ApplicationManagerImpl; import io.entgra.application.mgt.core.internal.DataHolder; import io.entgra.application.mgt.core.util.ConnectionManagerUtil; -import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; @@ -123,7 +122,8 @@ public class ApplicationManagementTest extends BaseTestCase { applicationArtifact.setScreenshots(screenshots); ApplicationManager manager = new ApplicationManagerImpl(); - manager.createEntApp(applicationWrapper, applicationArtifact); + ApplicationDTO applicationDTO = manager.uploadEntAppReleaseArtifacts(applicationWrapper, applicationArtifact); + manager.persistApplication(applicationDTO); } @DataProvider(name = "applicationIdDataProvider") diff --git a/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/ApplicationManagementPublisherAPI.java b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/ApplicationManagementPublisherAPI.java index 1cd1411da34..905f140de75 100644 --- a/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/ApplicationManagementPublisherAPI.java +++ b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/ApplicationManagementPublisherAPI.java @@ -624,6 +624,228 @@ public interface ApplicationManagementPublisherAPI { @Multipart(value = "screenshot3") Attachment screenshot3 ); + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/{deviceType}/public-app/{appId}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an application", + notes = "This will create a new public application release", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created an application.", + response = ApplicationRelease.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO creating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while creating the application.", + response = ErrorResponse.class) + }) + Response createPubAppRelease( + @ApiParam( + name = "deviceType", + value = "Device type that application is compatible with.", + required = true) + @PathParam("deviceType") String deviceType, + @ApiParam( + name = "appId", + value = "Id of the application.", + required = true) + @PathParam("appId") int appId, + @ApiParam( + name = "applicationRelease", + value = "The application release that need to be created.", + required = true) + @Multipart("applicationRelease") PublicAppReleaseWrapper publicAppReleaseWrapper, + @ApiParam( + name = "icon", + value = "Icon of the uploading application", + required = true) + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "Banner of the uploading application") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading application", + required = true) + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/web-app/{appId}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an application", + notes = "This will create a new web application release", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created an application.", + response = ApplicationRelease.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO creating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while creating the application.", + response = ErrorResponse.class) + }) + Response createWebAppRelease( + @ApiParam( + name = "appId", + value = "Id of the application.", + required = true) + @PathParam("appId") int appId, + @ApiParam( + name = "applicationRelease", + value = "The application release that need to be created.", + required = true) + @Multipart("applicationRelease") WebAppReleaseWrapper webAppReleaseWrapper, + @ApiParam( + name = "icon", + value = "Icon of the uploading application", + required = true) + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "Banner of the uploading application") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading application", + required = true) + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/{deviceType}/custom-app/{appId}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create an application", + notes = "This will create a new custom application release", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully created an application.", + response = ApplicationRelease.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n " + + "ApplicationDTO creating payload contains unacceptable or vulnerable data"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while creating the application.", + response = ErrorResponse.class) + }) + Response createCustomAppRelease( + @ApiParam( + name = "deviceType", + value = "Device type that application is compatible with.", + required = true) + @PathParam("deviceType") String deviceType, + @ApiParam( + name = "appId", + value = "Id of the application.", + required = true) + @PathParam("appId") int appId, + @ApiParam( + name = "applicationRelease", + value = "The application release that need to be created.", + required = true) + @Multipart("applicationRelease") CustomAppReleaseWrapper customAppReleaseWrapper, + @ApiParam( + name = "binaryFile", + value = "Binary file of uploading application", + required = true) + @Multipart(value = "binaryFile") Attachment binaryFile, + @ApiParam( + name = "icon", + value = "Icon of the uploading application", + required = true) + @Multipart(value = "icon") Attachment iconFile, + @ApiParam( + name = "banner", + value = "Banner of the uploading application") + @Multipart(value = "banner") Attachment bannerFile, + @ApiParam( + name = "screenshot1", + value = "Screen Shots of the uploading application", + required = true) + @Multipart(value = "screenshot1") Attachment screenshot1, + @ApiParam( + name = "screenshot2", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot2") Attachment screenshot2, + @ApiParam( + name = "screenshot3", + value = "Screen Shots of the uploading application", + required = false) + @Multipart(value = "screenshot3") Attachment screenshot3 + ); + @PUT @Path("/image-artifacts/{uuid}") @Produces(MediaType.APPLICATION_JSON) diff --git a/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/SPApplicationService.java b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/SPApplicationService.java new file mode 100644 index 00000000000..c39c9b8ea79 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/SPApplicationService.java @@ -0,0 +1,280 @@ +/* + * 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 io.entgra.application.mgt.publisher.api.services; + +import io.entgra.application.mgt.common.wrapper.ApplicationWrapper; +import io.entgra.application.mgt.common.wrapper.CustomAppWrapper; +import io.entgra.application.mgt.common.wrapper.PublicAppWrapper; +import io.entgra.application.mgt.common.wrapper.WebAppWrapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; + +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import java.util.List; + +/** + * This is the application registration service that exposed for apimApplicationRegistration + */ + +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "Service Provider Application Management Publisher Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "SPApplicationService"), + @ExtensionProperty(name = "context", value = "/api/application-mgt-publisher/v1.0/identity-server-applications"), + }) + } + ), + tags = { + @Tag(name = "application_management, device_management", description = "App publisher related APIs") + } +) +@Scopes( + scopes = { + @Scope( + name = "view a service provider applications", + description = "Get application details", + key = "perm:app:publisher:service-provider:view", + roles = {"Internal/devicemgt-user"}, + permissions = {"/app-mgt/publisher/service-provider/application/view"} + ), + @Scope( + name = "Create a service provider application", + description = "Update an application", + key = "perm:app:publisher:service-provider:create", + roles = {"Internal/devicemgt-user"}, + permissions = {"/app-mgt/publisher/service-provider/application/create"} + ), + @Scope( + name = "Attach a service provider application", + description = "Update an application", + key = "perm:app:publisher:service-provider:attach", + roles = {"Internal/devicemgt-user"}, + permissions = {"/app-mgt/publisher/service-provider/application/attach"} + ), + @Scope( + name = "Detach a service provider application", + description = "Update an application", + key = "perm:app:publisher:service-provider:detach", + roles = {"Internal/devicemgt-user"}, + permissions = {"/app-mgt/publisher/service-provider/application/detach"} + ) + } +) +@Path("/identity-server-applications") +@Api(value = "SPApplication Management") +@Produces(MediaType.APPLICATION_JSON) +public interface SPApplicationService { + + String SCOPE = "scope"; + + /** + * This method is used to register an APIM application for tenant domain. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("/identity-servers") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get the application of requesting application id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:view") + }) + } + ) + Response getIdentityServers(); + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("/identity-servers/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get the application of requesting application id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:view") + }) + } + ) + Response getIdentityServer(@PathParam("id") int id); + + /** + * This method is used to register an APIM application for tenant domain. + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{identity-server-id}/service-providers") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "get the application of requesting application id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:view") + }) + } + ) + Response getServiceProviders(@QueryParam("limit") Integer limit, @QueryParam("offset") Integer offset, + @PathParam("identity-server-id") int identityServerId); + + @Path("/{identity-server-id}/{service-provider-id}/attach") + @POST + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "get the application of requesting application id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:attach") + }) + } + ) + Response attachApps(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, List appIds); + + /** + * This method is used to register an APIM application for tenant domain. + */ + @Path("/{identity-server-id}/{service-provider-id}/detach") + @POST + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "get the application of requesting application id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:detach") + }) + } + ) + Response detachApps(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, List appIds); + + /** + * This method is used to register an APIM application for tenant domain. + */ + @Path("/{identity-server-id}/{service-provider-id}/create/ent-app") + @POST + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "get the application of requesting application id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:create") + }) + } + ) + Response createEntApp(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, ApplicationWrapper app); + + + /** + * This method is used to register an APIM application for tenant domain. + */ + @Path("/{identity-server-id}/{service-provider-id}/create/public-app") + @POST + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "get the application of requesting application id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:create") + }) + } + ) + Response createPubApp(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, PublicAppWrapper app); + + @Path("/{identity-server-id}/{service-provider-id}/create/web-app") + @POST + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "get the application of requesting application id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:create") + }) + } + ) + Response createWebApp(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, WebAppWrapper app); + + @Path("/{identity-server-id}/{service-provider-id}/create/custom-app") + @POST + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "get the application of requesting application id and state", + notes = "This will get the application identified by the application id and state, if exists", + tags = "ApplicationDTO Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:app:publisher:service-provider:create") + }) + } + ) + Response createCustomApp(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, CustomAppWrapper app); +} diff --git a/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java index 8b156bbf9d0..9aaeeb1d5a7 100644 --- a/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java +++ b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/impl/ApplicationManagementPublisherAPIImpl.java @@ -16,6 +16,9 @@ */ package io.entgra.application.mgt.publisher.api.services.impl; +import io.entgra.application.mgt.common.dto.ApplicationDTO; +import io.entgra.application.mgt.common.dto.ApplicationReleaseDTO; +import io.entgra.application.mgt.common.exception.ResourceManagementException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.cxf.jaxrs.ext.multipart.Attachment; @@ -47,6 +50,7 @@ import io.entgra.application.mgt.publisher.api.services.ApplicationManagementPub import io.entgra.application.mgt.common.exception.ApplicationManagementException; import io.entgra.application.mgt.common.services.ApplicationManager; import io.entgra.application.mgt.core.exception.NotFoundException; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; import java.io.IOException; import java.io.InputStream; @@ -182,15 +186,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem ApplicationManager applicationManager = APIUtil.getApplicationManager(); List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); try { - applicationManager.validateAppCreatingRequest(applicationWrapper); + applicationManager.validateAppCreatingRequest(applicationWrapper, true); applicationManager.validateReleaseCreatingRequest(applicationWrapper.getEntAppReleaseWrappers().get(0), applicationWrapper.getDeviceType()); applicationManager.validateBinaryArtifact(binaryFile); applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); // Created new Ent App - Application application = applicationManager.createEntApp(applicationWrapper, + ApplicationDTO applicationDTO = applicationManager.uploadEntAppReleaseArtifacts(applicationWrapper, constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList)); + Application application = applicationManager.persistApplication(applicationDTO); if (application != null) { return Response.status(Response.Status.CREATED).entity(application).build(); } else { @@ -226,14 +231,15 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem ApplicationManager applicationManager = APIUtil.getApplicationManager(); List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); try { - applicationManager.validateAppCreatingRequest(webAppWrapper); + applicationManager.validateAppCreatingRequest(webAppWrapper, true); applicationManager .validateReleaseCreatingRequest(webAppWrapper.getWebAppReleaseWrappers().get(0), Constants.ANY); applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); // Created new Web App - Application application = applicationManager.createWebClip(webAppWrapper, + ApplicationDTO applicationDTO = applicationManager.uploadWebAppReleaseArtifacts(webAppWrapper, constructApplicationArtifact(null, iconFile, bannerFile, attachmentList)); + Application application = applicationManager.persistApplication(applicationDTO); if (application != null) { return Response.status(Response.Status.CREATED).entity(application).build(); } else { @@ -269,14 +275,15 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem ApplicationManager applicationManager = APIUtil.getApplicationManager(); List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); try { - applicationManager.validateAppCreatingRequest(publicAppWrapper); + applicationManager.validateAppCreatingRequest(publicAppWrapper, true); applicationManager.validateReleaseCreatingRequest(publicAppWrapper.getPublicAppReleaseWrappers().get(0), publicAppWrapper.getDeviceType()); applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); // Created new Public App - Application application = applicationManager.createPublicApp(publicAppWrapper, + ApplicationDTO applicationDTO = applicationManager.uploadPublicAppReleaseArtifacts(publicAppWrapper, constructApplicationArtifact(null, iconFile, bannerFile, attachmentList)); + Application application = applicationManager.persistApplication(applicationDTO); if (application != null) { return Response.status(Response.Status.CREATED).entity(application).build(); } else { @@ -313,15 +320,16 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem ApplicationManager applicationManager = APIUtil.getApplicationManager(); List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); try { - applicationManager.validateAppCreatingRequest(customAppWrapper); + applicationManager.validateAppCreatingRequest(customAppWrapper, true); applicationManager.validateReleaseCreatingRequest(customAppWrapper.getCustomAppReleaseWrappers().get(0), customAppWrapper.getDeviceType()); applicationManager.validateBinaryArtifact(binaryFile); applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); // Created new Custom App - Application application = applicationManager.createCustomApp(customAppWrapper, + ApplicationDTO applicationDTO = applicationManager.uploadCustomAppReleaseArtifactsAndConstructAppDTO(customAppWrapper, constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList)); + Application application = applicationManager.persistApplication(applicationDTO); if (application != null) { return Response.status(Response.Status.CREATED).entity(application).build(); } else { @@ -348,7 +356,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) @Path("/{deviceType}/ent-app/{appId}") public Response createEntAppRelease( - @PathParam("deviceType") String deviceType, + @PathParam("deviceType") String deviceTypeName, @PathParam("appId") int appId, @Multipart("applicationRelease") EntAppReleaseWrapper entAppReleaseWrapper, @Multipart("binaryFile") Attachment binaryFile, @@ -357,34 +365,131 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem @Multipart("screenshot1") Attachment screenshot1, @Multipart("screenshot2") Attachment screenshot2, @Multipart("screenshot3") Attachment screenshot3) { - ApplicationManager applicationManager = APIUtil.getApplicationManager(); - List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); try { - applicationManager.validateReleaseCreatingRequest(entAppReleaseWrapper, deviceType); + ApplicationManager applicationManager = APIUtil.getApplicationManager(); applicationManager.validateBinaryArtifact(binaryFile); - applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList); - - // Created new Ent App release - ApplicationRelease release = applicationManager.createEntAppRelease(appId, entAppReleaseWrapper, - constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList)); - if (release != null) { - return Response.status(Response.Status.CREATED).entity(release).build(); - } else { - log.error("ApplicationDTO Creation Failed"); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); - } - } catch (BadRequestException e) { - String msg = "Found incompatible payload with enterprise app release creating request."; + ApplicationDTO applicationDTO = applicationManager.getApplication(appId); + DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + ApplicationArtifact artifact = constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList); + ApplicationReleaseDTO applicationReleaseDTO = applicationManager.uploadEntAppReleaseArtifacts( + entAppReleaseWrapper, artifact, deviceType.getName()); + ApplicationRelease release = applicationManager.createRelease(applicationDTO, applicationReleaseDTO, ApplicationType.ENTERPRISE); + return Response.status(Response.Status.CREATED).entity(release).build(); + } catch (RequestValidatingException e) { + String msg = "Error occurred while validating binaryArtifact"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } catch (ApplicationManagementException e) { - String msg = "Error occurred while creating the application"; + String msg = "Error occurred while creating application release for the application with the id " + appId; log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @POST + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/{deviceType}/public-app/{appId}") + @Override + public Response createPubAppRelease( + @PathParam("deviceType") String deviceTypeName, + @PathParam("appId") int appId, + @Multipart("applicationRelease") PublicAppReleaseWrapper publicAppReleaseWrapper, + @Multipart("icon") Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { + + try { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + ApplicationDTO applicationDTO = applicationManager.getApplication(appId); + DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + ApplicationArtifact artifact = constructApplicationArtifact(null, iconFile, bannerFile, attachmentList); + ApplicationReleaseDTO applicationReleaseDTO = applicationManager.uploadPubAppReleaseArtifacts( + publicAppReleaseWrapper, artifact, deviceType.getName()); + ApplicationRelease release = applicationManager.createRelease(applicationDTO, applicationReleaseDTO, ApplicationType.PUBLIC); + return Response.status(Response.Status.CREATED).entity(release).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating application release for the application with the id " + appId; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (ResourceManagementException e) { + String msg = "Error occurred while uploading application release artifacts"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @POST + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/web-app/{appId}") + @Override + public Response createWebAppRelease( + @PathParam("appId") int appId, + @Multipart("applicationRelease") WebAppReleaseWrapper webAppReleaseWrapper, + @Multipart("icon") Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { + try { + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + ApplicationDTO applicationDTO = applicationManager.getApplication(appId); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + ApplicationArtifact artifact = constructApplicationArtifact(null, iconFile, bannerFile, attachmentList); + ApplicationReleaseDTO applicationReleaseDTO = applicationManager.uploadWebAppReleaseArtifacts(webAppReleaseWrapper, artifact); + ApplicationRelease release = applicationManager.createRelease(applicationDTO, applicationReleaseDTO, ApplicationType.WEB_CLIP); + return Response.status(Response.Status.CREATED).entity(release).build(); + } catch (ResourceManagementException e) { + String msg = "Error occurred while uploading application release artifacts"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating application release for the application with the id " + appId; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @POST + @Consumes({"multipart/mixed", MediaType.MULTIPART_FORM_DATA}) + @Path("/{deviceType}/custom-app/{appId}") + @Override + public Response createCustomAppRelease( + @PathParam("deviceType") String deviceTypeName, + @PathParam("appId") int appId, + @Multipart("applicationRelease") CustomAppReleaseWrapper customAppReleaseWrapper, + @Multipart("binaryFile") Attachment binaryFile, + @Multipart("icon") Attachment iconFile, + @Multipart(value = "banner", required = false) Attachment bannerFile, + @Multipart("screenshot1") Attachment screenshot1, + @Multipart("screenshot2") Attachment screenshot2, + @Multipart("screenshot3") Attachment screenshot3) { + try { + APIUtil.getApplicationManager().validateBinaryArtifact(binaryFile); + ApplicationManager applicationManager = APIUtil.getApplicationManager(); + ApplicationDTO applicationDTO = applicationManager.getApplication(appId); + DeviceType deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId()); + List attachmentList = constructAttachmentList(screenshot1, screenshot2, screenshot3); + ApplicationArtifact artifact = constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList); + ApplicationReleaseDTO applicationReleaseDTO = applicationManager.uploadCustomAppReleaseArtifacts( + customAppReleaseWrapper, artifact, deviceType.getName()); + ApplicationRelease release = applicationManager.createRelease(applicationDTO, applicationReleaseDTO, ApplicationType.CUSTOM); + return Response.status(Response.Status.CREATED).entity(release).build(); } catch (RequestValidatingException e) { - String msg = "Error occurred while handling the application creating request"; + String msg = "Error occurred while validating binaryArtifact"; log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (ResourceManagementException e) { + String msg = "Error occurred while uploading application release artifacts"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while creating application release for the application with the id " + appId; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } } diff --git a/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/impl/SPApplicationServiceImpl.java b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/impl/SPApplicationServiceImpl.java new file mode 100644 index 00000000000..79a86655218 --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/impl/SPApplicationServiceImpl.java @@ -0,0 +1,211 @@ +/* + * 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 io.entgra.application.mgt.publisher.api.services.impl; + +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.common.IdentityServerList; +import io.entgra.application.mgt.common.SPApplicationListResponse; +import io.entgra.application.mgt.common.exception.ApplicationManagementException; +import io.entgra.application.mgt.common.exception.RequestValidatingException; +import io.entgra.application.mgt.common.response.Application; +import io.entgra.application.mgt.common.services.SPApplicationManager; +import io.entgra.application.mgt.common.wrapper.ApplicationWrapper; +import io.entgra.application.mgt.common.wrapper.CustomAppWrapper; +import io.entgra.application.mgt.common.wrapper.PublicAppWrapper; +import io.entgra.application.mgt.common.wrapper.WebAppWrapper; +import io.entgra.application.mgt.core.exception.BadRequestException; +import io.entgra.application.mgt.core.util.APIUtil; +import io.entgra.application.mgt.publisher.api.services.SPApplicationService; +import io.entgra.application.mgt.publisher.api.services.util.SPAppRequestHandlerUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +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; +import java.util.List; + + +@Produces(MediaType.APPLICATION_JSON) +@Path("/identity-server-applications") +public class SPApplicationServiceImpl implements SPApplicationService { + private static final Log log = LogFactory.getLog(SPApplicationServiceImpl.class); + + @Path("/identity-servers") + @GET + @Override + public Response getIdentityServers() { + try { + SPApplicationManager spAppManager = APIUtil.getSPApplicationManager(); + IdentityServerList identityServers = spAppManager.getIdentityServers(); + return Response.status(Response.Status.OK).entity(identityServers).build(); + } catch (ApplicationManagementException e) { + String errMsg = "Error occurred while trying to merge identity server apps with existing apps"; + log.error(errMsg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + } + } + + @Path("/identity-servers/{id}") + @GET + @Override + public Response getIdentityServer(@PathParam("id") int id) { + try { + SPApplicationManager spAppManager = APIUtil.getSPApplicationManager(); + IdentityServer identityServer = spAppManager.getIdentityServer(id); + return Response.status(Response.Status.OK).entity(identityServer).build(); + } catch (ApplicationManagementException e) { + String errMsg = "Error occurred while trying to merge identity server apps with existing apps"; + log.error(errMsg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + } + } + + @Path("/{identity-server-id}/service-providers") + @GET + @Override + public Response getServiceProviders(@QueryParam("limit") Integer limit, @QueryParam("offset") Integer offset, + @PathParam("identity-server-id") int identityServerId) { + try { + SPApplicationManager spAppManager = APIUtil.getSPApplicationManager(); + SPApplicationListResponse applications = SPAppRequestHandlerUtil. + getServiceProvidersFromIdentityServer(identityServerId, limit, offset); + spAppManager.addExistingApps(identityServerId, applications.getApplications()); + return Response.status(Response.Status.OK).entity(applications).build(); + } catch (ApplicationManagementException e) { + String errMsg = "Error occurred while trying to merge identity server apps with existing apps"; + log.error(errMsg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errMsg).build(); + } + } + + @Path("/{identity-server-id}/{service-provider-id}/attach") + @POST + @Override + public Response attachApps(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, List appIds) { + SPApplicationManager spApplicationManager = APIUtil.getSPApplicationManager(); + try { + validateServiceProviderUID(identityServerId, serviceProviderId); + spApplicationManager.validateAttachAppsRequest(identityServerId, appIds); + spApplicationManager.attachSPApplications(identityServerId, serviceProviderId, appIds); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while attaching apps to service provider with the id" + serviceProviderId; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).build(); + } + + @Path("/{identity-server-id}/{service-provider-id}/detach") + @POST + @Override + public Response detachApps(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, List appIds) { + SPApplicationManager spApplicationManager = APIUtil.getSPApplicationManager(); + try { + validateServiceProviderUID(identityServerId, serviceProviderId); + spApplicationManager.validateDetachAppsRequest(identityServerId, serviceProviderId, appIds); + spApplicationManager.detachSPApplications(identityServerId, serviceProviderId, appIds); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while attaching apps to service provider with the id" + serviceProviderId; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + return Response.status(Response.Status.OK).build(); + } + + @Path("/{identity-server-id}/{service-provider-id}/create/ent-app") + @POST + @Override + public Response createEntApp(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, ApplicationWrapper app) { + return createSPApplication(identityServerId, serviceProviderId, app); + } + + @Path("/{identity-server-id}/{service-provider-id}/create/public-app") + @POST + @Override + public Response createPubApp(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, PublicAppWrapper app) { + return createSPApplication(identityServerId, serviceProviderId, app); + } + + @Path("/{identity-server-id}/{service-provider-id}/create/web-app") + @POST + @Override + public Response createWebApp(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, WebAppWrapper app) { + return createSPApplication(identityServerId, serviceProviderId, app); + } + + @Path("/{identity-server-id}/{service-provider-id}/create/custom-app") + @POST + @Override + public Response createCustomApp(@PathParam("identity-server-id") int identityServerId, + @PathParam("service-provider-id") String serviceProviderId, CustomAppWrapper app) { + return createSPApplication(identityServerId, serviceProviderId, app); + } + + private Response createSPApplication(int identityServerId, String serviceProviderId, T appWrapper) { + try { + validateServiceProviderUID(identityServerId, serviceProviderId); + SPApplicationManager spApplicationManager = APIUtil.getSPApplicationManager(); + Application createdApp = spApplicationManager.createSPApplication(appWrapper, identityServerId, serviceProviderId); + return Response.status(Response.Status.CREATED).entity(createdApp).build(); + } catch (BadRequestException e) { + String msg = "Found incompatible payload with create service provider app request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } catch (RequestValidatingException e) { + String msg = "Found invalid release payload with create service provider app request."; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + catch (ApplicationManagementException e) { + String msg = "Error occurred while creating service provider app"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + private void validateServiceProviderUID(int identityServerId, String spUID) throws + ApplicationManagementException { + try { + boolean isSPAppExists = SPAppRequestHandlerUtil. + isSPApplicationExist(identityServerId, spUID); + if (!isSPAppExists) { + String errMsg = "Service provider with the uid " + spUID + " does not exist."; + log.error(errMsg); + throw new BadRequestException(errMsg); + } + } catch (ApplicationManagementException e) { + String errMsg = "Error occurred while trying to validate service provider uid"; + log.error(errMsg, e); + throw new ApplicationManagementException(errMsg, e); + } + } + + +} \ No newline at end of file diff --git a/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/util/SPAppRequestHandlerUtil.java b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/util/SPAppRequestHandlerUtil.java new file mode 100644 index 00000000000..307cb91342f --- /dev/null +++ b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/java/io/entgra/application/mgt/publisher/api/services/util/SPAppRequestHandlerUtil.java @@ -0,0 +1,137 @@ +package io.entgra.application.mgt.publisher.api.services.util; + +import com.google.gson.Gson; +import io.entgra.application.mgt.common.IdentityServer; +import io.entgra.application.mgt.common.SPApplication; +import io.entgra.application.mgt.common.SPApplicationListResponse; +import io.entgra.application.mgt.common.exception.ApplicationManagementException; +import io.entgra.application.mgt.common.services.SPApplicationManager; +import io.entgra.application.mgt.core.util.APIUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.wso2.carbon.device.mgt.core.common.util.HttpUtil; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.UriBuilder; +import java.io.IOException; +import java.net.URI; + +public class SPAppRequestHandlerUtil { + + private static final Log log = LogFactory.getLog(SPAppRequestHandlerUtil.class); + + public static boolean isSPApplicationExist(int identityServerId, String spAppId) throws ApplicationManagementException { + SPApplication application = retrieveSPApplication(identityServerId, spAppId); + if (application == null) { + return false; + } + return true; + } + + public static SPApplicationListResponse getServiceProvidersFromIdentityServer(int identityServerId, Integer limit, Integer offSet) + throws ApplicationManagementException { + return retrieveSPApplications(identityServerId, limit, offSet); + } + + public static SPApplication retrieveSPApplication(int identityServerId, String spAppId) + throws ApplicationManagementException { + IdentityServer identityServer = getIdentityServer(identityServerId); + HttpGet req = new HttpGet(); + URI uri = HttpUtil.createURI(getSPApplicationsAPI(identityServer)); + uri = UriBuilder.fromUri(uri).path(spAppId).build(); + req.setURI(uri); + CloseableHttpClient client = HttpClients.createDefault(); + try { + HttpResponse response = invokeISAPI(identityServer, client, req); + String responseBody = HttpUtil.getResponseString(response); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + return new Gson().fromJson(responseBody, + SPApplication.class); + } + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) { + return null; + } + String msg = "Error occurred while calling SP Applications API"; + log.error(msg); + throw new ApplicationManagementException(msg); + } catch (IOException e) { + String msg = "Error occurred while calling SP Applications API"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + try { + client.close(); + } catch (IOException e) { + log.error("Error occurred while closing http connection"); + } + } + } + + + public static SPApplicationListResponse retrieveSPApplications(int identityServerId, Integer limit, Integer offset) + throws ApplicationManagementException { + IdentityServer identityServer = getIdentityServer(identityServerId); + HttpGet req = new HttpGet(); + URI uri = HttpUtil.createURI(getSPApplicationsAPI(identityServer)); + UriBuilder uriBuilder = UriBuilder.fromUri(uri); + if (limit != null) { + uriBuilder = uriBuilder.queryParam(io.entgra.application.mgt.core.util.Constants.LIMIT_QUERY_PARAM, limit); + } + if (offset != null) { + uriBuilder = uriBuilder.queryParam(io.entgra.application.mgt.core.util.Constants.OFFSET_QUERY_PARAM, offset); + } + uri = uriBuilder.build(); + req.setURI(uri); + CloseableHttpClient client = HttpClients.createDefault(); + try { + HttpResponse response = invokeISAPI(identityServer, client, req); + String responseBody = HttpUtil.getResponseString(response); + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + return new Gson().fromJson(responseBody, + SPApplicationListResponse.class); + } + String msg = "Error occurred while calling SP Applications API"; + log.error(msg); + throw new ApplicationManagementException(msg); + } catch (IOException e) { + String msg = "Error occurred while calling SP Applications API"; + log.error(msg, e); + throw new ApplicationManagementException(msg, e); + } finally { + try { + client.close(); + } catch (IOException e) { + log.error("Error occurred while closing http connection"); + } + } + } + + public static IdentityServer getIdentityServer(int identityServerId) throws ApplicationManagementException { + SPApplicationManager spApplicationManager = APIUtil.getSPApplicationManager(); + return spApplicationManager.getIdentityServer(identityServerId); + } + + public static HttpResponse invokeISAPI(IdentityServer identityServer, HttpClient client, HttpRequestBase request) throws IOException { + setBasicAuthHeader(identityServer, request); + return client.execute(request); + } + + public static void setBasicAuthHeader(IdentityServer identityServer, HttpRequestBase request) { + String basicAuthHeader = HttpUtil.getBasicAuthBase64Header(identityServer.getUserName(), + identityServer.getPassword()); + request.setHeader(HttpHeaders.AUTHORIZATION, basicAuthHeader); + } + + private static String getSPApplicationsAPI(IdentityServer identityServer) { + String api = identityServer.getSpAppsApi(); + return api; + } + +} \ No newline at end of file diff --git a/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/webapp/WEB-INF/cxf-servlet.xml index 47dcef91e1b..da39cd93a8b 100644 --- a/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/application-mgt/io.entgra.application.mgt.publisher.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -25,6 +25,7 @@ + @@ -54,6 +55,7 @@ + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/common/Constants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/common/Constants.java new file mode 100644 index 00000000000..2f9a7207b89 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/common/Constants.java @@ -0,0 +1,10 @@ +package org.wso2.carbon.device.mgt.core.common; + +public class Constants { + public static final String SCHEME_SEPARATOR = "://"; + public static final String COLON = ":"; + public static final String URI_QUERY_SEPARATOR = "?"; + public static final String URI_SEPARATOR = "/"; + public static final String BASIC_AUTH_HEADER_PREFIX = "Basic "; + public static final String BEARER = "Bearer "; +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/common/util/FileUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/common/util/FileUtil.java new file mode 100644 index 00000000000..28a5084003b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/common/util/FileUtil.java @@ -0,0 +1,24 @@ +package org.wso2.carbon.device.mgt.core.common.util; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Base64; + +public class FileUtil { + + public static String removePathSeparatorFromBase64String(String base64String) { + String partSeparator = ","; + if (base64String.contains(partSeparator)) { + return base64String.split(partSeparator)[1]; + } + return base64String; + } + + public static InputStream base64ToInputStream(String base64) { + base64 = FileUtil.removePathSeparatorFromBase64String(base64); + byte[] base64Bytes = Base64.getDecoder().decode(base64); + return new ByteArrayInputStream(base64Bytes); + } + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/common/util/HttpUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/common/util/HttpUtil.java new file mode 100644 index 00000000000..130cd07c490 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/common/util/HttpUtil.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2020, Entgra (pvt) Ltd. (http://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 org.wso2.carbon.device.mgt.core.common.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpResponse; +import org.apache.http.entity.ContentType; +import org.apache.http.util.EntityUtils; +import org.wso2.carbon.device.mgt.core.common.Constants; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class HttpUtil { + + public static URI createURI(String uriString) { + uriString = uriString.replace(" ", "%20"); + return URI.create(uriString); + } + + public static String getBasicAuthBase64Header(String userName, String password) { + return Constants.BASIC_AUTH_HEADER_PREFIX + getBase64Encode(userName, password); + } + + public static String getBase64Encode(String key, String value) { + return new String(Base64.encodeBase64((key + ":" + value).getBytes())); + } + + public static String getRequestSubPathFromEnd(URI requestUri, int position) { + if (requestUri.getPath() != null) { + String[] pathList = requestUri.getPath().split("/"); + if (pathList.length - 1 >= position) { + return pathList[pathList.length - 1 - position]; + } + } + return null; + } + + public static String getRequestSubPath(String fullPath, int position) { + String[] pathList = fullPath.split("/"); + if (pathList.length - 1 > position) { + String path = pathList[position + 1]; + if(path.contains(Constants.URI_QUERY_SEPARATOR)) { + path = path.substring(0, path.indexOf(Constants.URI_QUERY_SEPARATOR)); + } + return path; + } + return null; + } + + public static String getResponseString(HttpResponse response) throws IOException { + return EntityUtils.toString(response.getEntity()); + } + + public static boolean isQueryParamExist(String param, URI request) { + Map> queryMap = getQueryMap(request); + return queryMap.containsKey(param); + } + public static String getFirstQueryValue(String param, Map> queryMap) { + List valueList = queryMap.get(param); + String firstValue = null; + if(valueList != null) { + firstValue = valueList.get(0); + } + return firstValue; + } + public static Map> getQueryMap(String uri) { + String query = getQueryFromURIPath(uri); + Map> map = new HashMap<>(); + if (query != null) { + String[] params = query.split("&"); + for (String param : params) { + String[] paramArr = param.split("="); + if (paramArr.length == 2) { + String name = paramArr[0]; + String value = paramArr[1]; + if (!map.containsKey(name)) { + List valueList = new ArrayList<>(); + map.put(name, valueList); + } + map.get(name).add(value); + } + } + } + return map; + } + public static Map> getQueryMap(URI request) { + String query = request.getQuery(); + Map> map = new HashMap<>(); + if (query != null) { + String[] params = query.split("&"); + for (String param : params) { + String[] paramArr = param.split("="); + if (paramArr.length == 2) { + String name = paramArr[0]; + String value = paramArr[1]; + if (!map.containsKey(name)) { + List valueList = new ArrayList<>(); + map.put(name, valueList); + } + map.get(name).add(value); + } + } + } + return map; + } + public static String getQueryFromURIPath(String uri) { + String query = null; + if (uri.length() > "?".length() && uri.contains("?")) { + query = uri.substring(uri.lastIndexOf("?") + "?".length()); + } + if (StringUtils.isEmpty(query)) { + query = null; + } + return query; + } + + public static String getContentType(HttpResponse response) { + ContentType contentType = ContentType.getOrDefault(response.getEntity()); + return contentType.getMimeType(); + } +} diff --git a/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml b/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml index fa4ce1eb53c..428fc0e1346 100644 --- a/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml +++ b/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/conf/application-mgt.xml @@ -22,6 +22,9 @@ jdbc/APPM_DS + + io.entgra.application.mgt.core.impl.SPApplicationManagerImpl + io.entgra.application.mgt.core.impl.ApplicationManagerImpl diff --git a/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/conf_templates/templates/repository/conf/application-mgt.xml.j2 b/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/conf_templates/templates/repository/conf/application-mgt.xml.j2 index 21ce676f3f5..bd2cc9141cb 100644 --- a/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/conf_templates/templates/repository/conf/application-mgt.xml.j2 +++ b/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/conf_templates/templates/repository/conf/application-mgt.xml.j2 @@ -22,6 +22,13 @@ jdbc/APPM_DS + + {% if application_mgt_conf.extension.isapplication_manager is defined %} + {{application_mgt_conf.extension.isapplication_manager}} + {% else %} + io.entgra.application.mgt.core.impl.SPApplicationManagerImpl + {% endif %} + {% if application_mgt_conf.extension.application_manager is defined %} {{application_mgt_conf.extension.application_manager}} diff --git a/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql b/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql index 110ccdc606d..8985d3637bf 100644 --- a/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql +++ b/features/application-mgt/io.entgra.application.mgt.server.feature/src/main/resources/dbscripts/cdm/application-mgt/mysql.sql @@ -274,4 +274,39 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION( SCHEDULED_TIMESTAMP TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, DELETED BOOLEAN, PRIMARY KEY (ID) -); \ No newline at end of file +); + +-- ----------------------------------------------------- +-- Table AP_IDENTITY_SERVER +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS AP_IDENTITY_SERVER +( + ID INT AUTO_INCREMENT + PRIMARY KEY, + NAME VARCHAR(255) NOT NULL, + DESCRIPTION VARCHAR(255) NOT NULL, + URL VARCHAR(255) NOT NULL, + SP_APPS_URI VARCHAR(255) NOT NULL, + SP_APPS_API VARCHAR(255) NULL, + TENANT_ID INT NOT NULL, + USERNAME VARCHAR(255) NOT NULL, + PASSWORD VARCHAR(255) NOT NULL +) + +-- ----------------------------------------------------- +-- Table AP_IS_SP_APP_MAPPING +-- -----------------------------------------------------; + CREATE TABLE IF NOT EXISTS AP_IS_SP_APP_MAPPING + ( + ID INT AUTO_INCREMENT + PRIMARY KEY, + SP_UID VARCHAR(255) NOT NULL, + AP_APP_ID INT NOT NULL, + IS_ID INT NOT NULL, + TENANT_ID INT NOT NULL, + CONSTRAINT AP_IS_SP_APP_MAPPING_AP_APP_ID_fk + FOREIGN KEY (AP_APP_ID) REFERENCES AP_APP (ID), + CONSTRAINT AP_IS_SP_APP_MAPPING_AP_IDENTITY_SERVER_ID_fk + FOREIGN KEY (IS_ID) REFERENCES AP_IDENTITY_SERVER (ID) + ); + diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml index 88d9b47d294..bc6be595996 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml @@ -36,6 +36,10 @@ perm:app:review:view perm:app:review:update + perm:app:publisher:service-provider:view + perm:app:publisher:service-provider:create + perm:app:publisher:service-provider:attach + perm:app:publisher:service-provider:detach perm:app:publisher:view perm:app:publisher:update perm:app:store:view diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/mdm-ui-config.xml.j2 b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/mdm-ui-config.xml.j2 index 077e55c9ed3..244e90ce97c 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/mdm-ui-config.xml.j2 +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf_templates/templates/repository/conf/mdm-ui-config.xml.j2 @@ -57,6 +57,10 @@ perm:app:review:view perm:app:review:update + perm:app:publisher:service-provider:view + perm:app:publisher:service-provider:create + perm:app:publisher:service-provider:attach + perm:app:publisher:service-provider:detach perm:app:publisher:view perm:app:publisher:update perm:app:store:view