diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java index d9ac61f4f4..5135a25db1 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/impl/ApplicationManagerImpl.java @@ -67,7 +67,7 @@ import org.wso2.carbon.device.application.mgt.core.exception.UnexpectedServerErr import org.wso2.carbon.device.application.mgt.core.exception.ValidationException; import org.wso2.carbon.device.application.mgt.core.exception.VisibilityManagementDAOException; import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; -import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManger; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; import org.wso2.carbon.device.application.mgt.core.util.Constants; import org.wso2.carbon.device.mgt.common.DeviceManagementException; @@ -104,11 +104,11 @@ public class ApplicationManagerImpl implements ApplicationManager { private ApplicationDAO applicationDAO; private ApplicationReleaseDAO applicationReleaseDAO; private LifecycleStateDAO lifecycleStateDAO; - private LifecycleStateManger lifecycleStateManger; + private LifecycleStateManager lifecycleStateManager; public ApplicationManagerImpl() { initDataAccessObjects(); - lifecycleStateManger = DataHolder.getInstance().getLifecycleStateManager(); + lifecycleStateManager = DataHolder.getInstance().getLifecycleStateManager(); } private void initDataAccessObjects() { @@ -122,8 +122,8 @@ public class ApplicationManagerImpl implements ApplicationManager { * The responsbility of this method is the creating an application. * @param applicationWrapper ApplicationDTO that need to be created. * @return {@link ApplicationDTO} - * @throws RequestValidatingException if application creating request is invalid, returns {@link RequestValidatingException} - * @throws ApplicationManagementException Catch all other throwing exceptions and returns {@link ApplicationManagementException} + * @throws RequestValidatingException if application creating request is invalid, + * @throws ApplicationManagementException Catch all other throwing exceptions and throw {@link ApplicationManagementException} */ @Override public Application createApplication(ApplicationWrapper applicationWrapper, @@ -504,7 +504,8 @@ public class ApplicationManagerImpl implements ApplicationManager { String packageName = this.applicationReleaseDAO.getPackageName(applicationId, tenantId); if (packageName != null && !packageName.equals(applicationRelease.getPackageName())) { throw new BadRequestException( - "Package name in the payload is different from the existing package name of other application releases."); + "Package name in the payload is different from the existing package name of other application" + + " releases."); } applicationRelease = this.applicationReleaseDAO .createRelease(applicationRelease, existingApplication.getId(), tenantId); @@ -810,8 +811,8 @@ public class ApplicationManagerImpl implements ApplicationManager { .getLatestLifeCycleState(applicationId, applicationRelease.getUuid()); LifecycleStateDTO newAppLifecycleState = getLifecycleStateInstance(AppLifecycleState.REMOVED.toString(), appLifecycleState.getCurrentState()); - if (lifecycleStateManger.isValidStateChange(newAppLifecycleState.getPreviousState(), - newAppLifecycleState.getCurrentState())) { + if (lifecycleStateManager.isValidStateChange(newAppLifecycleState.getPreviousState(), + newAppLifecycleState.getCurrentState(), userName, tenantId)) { this.lifecycleStateDAO .addLifecycleState(newAppLifecycleState, applicationId, applicationRelease.getUuid(), tenantId); @@ -821,7 +822,7 @@ public class ApplicationManagerImpl implements ApplicationManager { AppLifecycleState.REMOVED.toString()); for (String nextState : lifecycleFlow) { LifecycleStateDTO lifecycleState = getLifecycleStateInstance(nextState, currentState); - if (lifecycleStateManger.isValidStateChange(currentState, nextState)) { + if (lifecycleStateManager.isValidStateChange(currentState, nextState, userName, tenantId)) { this.lifecycleStateDAO .addLifecycleState(lifecycleState, applicationId, applicationRelease.getUuid(), tenantId); @@ -871,7 +872,7 @@ public class ApplicationManagerImpl implements ApplicationManager { if (currentNode.equals(finish)) { break; } else { - Set nextStates = lifecycleStateManger.getNextLifecycleStates(currentNode); + Set nextStates = lifecycleStateManager.getNextLifecycleStates(currentNode); if (nextStates.contains(finish)) { queue = new LinkedList<>(); queue.add(finish); @@ -940,8 +941,8 @@ public class ApplicationManagerImpl implements ApplicationManager { .equals(currentState) || AppLifecycleState.UNPUBLISHED.toString().equals(currentState)) { LifecycleStateDTO newAppLifecycleState = getLifecycleStateInstance(AppLifecycleState.REMOVED.toString(), appLifecycleState.getCurrentState()); - if (lifecycleStateManger.isValidStateChange(newAppLifecycleState.getPreviousState(), - newAppLifecycleState.getCurrentState())) { + if (lifecycleStateManager.isValidStateChange(newAppLifecycleState.getPreviousState(), + newAppLifecycleState.getCurrentState(), userName, tenantId)) { this.lifecycleStateDAO .addLifecycleState(newAppLifecycleState, applicationId, applicationRelease.getUuid(), tenantId); @@ -951,7 +952,7 @@ public class ApplicationManagerImpl implements ApplicationManager { AppLifecycleState.REMOVED.toString()); for (String nextState : lifecycleFlow) { LifecycleStateDTO lifecycleState = getLifecycleStateInstance(nextState, currentState); - if (lifecycleStateManger.isValidStateChange(currentState, nextState)) { + if (lifecycleStateManager.isValidStateChange(currentState, nextState, userName, tenantId)) { this.lifecycleStateDAO .addLifecycleState(lifecycleState, applicationId, applicationRelease.getUuid(), tenantId); @@ -1187,7 +1188,8 @@ public class ApplicationManagerImpl implements ApplicationManager { } /** - * To validate a app release creating request and app updating request to make sure all the pre-conditions satisfied. + * To validate a app release creating request and app updating request to make sure all the pre-conditions + * satisfied. * * @param applicationRelease ApplicationReleaseDTO that need to be created. * @throws ApplicationManagementException ApplicationDTO Management Exception. @@ -1210,8 +1212,7 @@ public class ApplicationManagerImpl implements ApplicationManager { if (lifecycleState == null) { return null; } - lifecycleState.setNextStates( - new ArrayList<>(lifecycleStateManger.getNextLifecycleStates(lifecycleState.getCurrentState()))); + lifecycleState.setNextStates(new ArrayList<>(lifecycleStateManager.getNextLifecycleStates(lifecycleState.getCurrentState()))); } catch (LifeCycleManagementDAOException e) { throw new ApplicationManagementException("Failed to get lifecycle state from database", e); @@ -1241,12 +1242,12 @@ public class ApplicationManagerImpl implements ApplicationManager { + " and application release UUID: " + releaseUuid); } state.setPreviousState(currentState.getCurrentState()); - String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); state.setUpdatedBy(userName); if (state.getCurrentState() != null && state.getPreviousState() != null) { - if (lifecycleStateManger.isValidStateChange(state.getPreviousState(), state.getCurrentState())) { + if (lifecycleStateManager.isValidStateChange(state.getPreviousState(), state.getCurrentState(), + userName, tenantId)) { //todo if current state of the adding lifecycle state is PUBLISHED, need to check whether is there //todo any other application release in PUBLISHED state for the application( i.e for the appid) this.lifecycleStateDAO.addLifecycleState(state, applicationId, releaseUuid, tenantId); diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ApplicationManagementServiceComponent.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ApplicationManagementServiceComponent.java index cca3e32608..ecf8280eb0 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ApplicationManagementServiceComponent.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/ApplicationManagementServiceComponent.java @@ -31,7 +31,7 @@ import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; import org.wso2.carbon.device.application.mgt.common.config.UIConfiguration; import org.wso2.carbon.device.application.mgt.core.dao.common.ApplicationManagementDAOFactory; import org.wso2.carbon.device.application.mgt.core.impl.AppmDataHandlerImpl; -import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManger; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; import org.wso2.carbon.device.application.mgt.core.lifecycle.config.LifecycleState; import org.wso2.carbon.device.application.mgt.core.util.ApplicationManagementUtil; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; @@ -78,10 +78,10 @@ public class ApplicationManagementServiceComponent { List lifecycleStates = ConfigurationManager.getInstance(). getConfiguration().getLifecycleStates(); - LifecycleStateManger lifecycleStateManger = ApplicationManagementUtil.getLifecycleStateMangerInstance(); - lifecycleStateManger.init(lifecycleStates); - DataHolder.getInstance().setLifecycleStateManger(lifecycleStateManger); - bundleContext.registerService(LifecycleStateManger.class.getName(), lifecycleStateManger, null); + LifecycleStateManager lifecycleStateManager = ApplicationManagementUtil.getLifecycleStateMangerInstance(); + lifecycleStateManager.init(lifecycleStates); + DataHolder.getInstance().setLifecycleStateManger(lifecycleStateManager); + bundleContext.registerService(LifecycleStateManager.class.getName(), lifecycleStateManager, null); ApplicationManager applicationManager = ApplicationManagementUtil.getApplicationManagerInstance(); applicationManager diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java index 56d62f51ee..73efa24598 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/internal/DataHolder.java @@ -23,7 +23,7 @@ import org.wso2.carbon.device.application.mgt.common.services.ApplicationStorage import org.wso2.carbon.device.application.mgt.common.services.AppmDataHandler; import org.wso2.carbon.device.application.mgt.common.services.ReviewManager; import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; -import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManger; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.user.core.service.RealmService; @@ -44,7 +44,7 @@ public class DataHolder { private ApplicationStorageManager applicationStorageManager; - private LifecycleStateManger lifecycleStateManger; + private LifecycleStateManager lifecycleStateManager; private AppmDataHandler configManager; @@ -106,12 +106,12 @@ public class DataHolder { return applicationStorageManager; } - public LifecycleStateManger getLifecycleStateManager() { - return lifecycleStateManger; + public LifecycleStateManager getLifecycleStateManager() { + return lifecycleStateManager; } - public void setLifecycleStateManger(LifecycleStateManger lifecycleStateManger) { - this.lifecycleStateManger = lifecycleStateManger; + public void setLifecycleStateManger(LifecycleStateManager lifecycleStateManager) { + this.lifecycleStateManager = lifecycleStateManager; } public AppmDataHandler getConfigManager() { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/LifecycleStateManager.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/LifecycleStateManager.java new file mode 100644 index 0000000000..6b97149f26 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/LifecycleStateManager.java @@ -0,0 +1,157 @@ +/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.application.mgt.core.lifecycle; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; +import org.wso2.carbon.device.application.mgt.core.internal.DataHolder; +import org.wso2.carbon.device.application.mgt.core.lifecycle.config.LifecycleState; +import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; +import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils; +import org.wso2.carbon.device.mgt.core.search.mgt.Constants; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * This class represents the activities related to lifecycle management + */ +public class LifecycleStateManager { + + private Map lifecycleStates; + private static Log log = LogFactory.getLog(LifecycleStateManager.class); + + public void init(List states) throws LifecycleManagementException { + lifecycleStates = new HashMap<>(); + for (LifecycleState s : states) { + if (s.getProceedingStates() != null) { + s.getProceedingStates().replaceAll(String::toUpperCase); + } + lifecycleStates.put(s.getName().toUpperCase(), new State(s.getName().toUpperCase(), + s.getProceedingStates(), s.getPermission(), s.isAppUpdatable(), s.isAppInstallable(), + s.isInitialState(), s.isEndState())); + try { + PermissionUtils.putPermission(s.getPermission()); + } catch (PermissionManagementException e) { + String msg = "Error when adding permission " + s.getPermission() + " related to the state: " + + s.getName(); + log.error(msg, e); + throw new LifecycleManagementException(msg, e); + } + } + } + + + public Set getNextLifecycleStates(String currentLifecycleState) { + return lifecycleStates.get(currentLifecycleState.toUpperCase()).getProceedingStates(); + } + + public boolean isValidStateChange(String currentState, String nextState, String username, int tenantId) throws + LifecycleManagementException { + + UserRealm userRealm; + String permission = getPermissionForStateChange(nextState); + if (permission != null) { + try { + userRealm = DataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId); + if (userRealm != null && userRealm.getAuthorizationManager() != null && + userRealm.getAuthorizationManager().isUserAuthorized(username, + PermissionUtils.getAbsolutePermissionPath(permission), + Constants.UI_EXECUTE)) { + if (currentState.equalsIgnoreCase(nextState)) { + return true; + } + State state = getMatchingState(currentState); + if (state != null) { + return getMatchingNextState(state.getProceedingStates(), nextState); + } + return false; + } + return false; + } catch (UserStoreException e) { + throw new LifecycleManagementException( + "UserStoreException exception from changing the state from : " + currentState + " to: " + + nextState + " with username : " + username + " and tenant Id : " + tenantId, e); + } + } else { + throw new LifecycleManagementException( + "Required permissions cannot be found for the state : " + nextState); + } + } + + private State getMatchingState(String currentState) { + Iterator it = lifecycleStates.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry) it.next(); + if (pair.getKey().toString().equalsIgnoreCase(currentState)) { + return lifecycleStates.get(pair.getKey().toString()); + } + } + return null; + } + + + private boolean getMatchingNextState(Set proceedingStates, String nextState) { + for (String state : proceedingStates) { + if (state.equalsIgnoreCase(nextState)) { + return true; + } + } + return false; + } + + private String getPermissionForStateChange(String nextState) { + Iterator it = lifecycleStates.entrySet().iterator(); + State nextLifecycleState; + while (it.hasNext()) { + Map.Entry pair = (Map.Entry) it.next(); + if (pair.getKey().toString().equalsIgnoreCase(nextState)) { + nextLifecycleState = lifecycleStates.get(nextState); + return nextLifecycleState.getPermission(); + } + it.remove(); + } + return null; + } + + public boolean isUpdatable(String state) { + State currentState = getMatchingState(state); + if (currentState.getIsAppUpdatable()) { + return true; + } + return false; + } + + public boolean isInstallable(String state) { + State currentState = getMatchingState(state); + if (currentState.getIsAppInstallable()) { + return true; + } + return false; + } + + public void setLifecycleStates(Map lifecycleStates) { + this.lifecycleStates = lifecycleStates; + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/LifecycleStateManger.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/LifecycleStateManger.java deleted file mode 100644 index a201712642..0000000000 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/LifecycleStateManger.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.wso2.carbon.device.application.mgt.core.lifecycle; - -import org.wso2.carbon.device.application.mgt.core.lifecycle.config.LifecycleState; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * This class represents the activities related to lifecycle management - */ -public class LifecycleStateManger { - - private Map lifecycleStates; - - public void init(List states){ - lifecycleStates = new HashMap<>(); - for (LifecycleState s : states) { - if (s.getProceedingStates() != null) { - s.getProceedingStates().replaceAll(String::toUpperCase); - } - lifecycleStates.put(s.getName().toUpperCase(), new State(s.getName().toUpperCase(), s.getProceedingStates())); - - } - } - - public Set getNextLifecycleStates(String currentLifecycleState) { - return lifecycleStates.get(currentLifecycleState.toUpperCase()).getProceedingStates(); - } - - public boolean isValidStateChange(String currentState, String nextState) { - if (currentState.equalsIgnoreCase(nextState)) { - return true; - } - - State state = getMatchingState(currentState); - if (state != null) { - return getMatchingNextState(state.getProceedingStates(), nextState); - } - return false; - } - - private State getMatchingState(String currentState) { - Iterator it = lifecycleStates.entrySet().iterator(); - while (it.hasNext()) { - Map.Entry pair = (Map.Entry)it.next(); - if(pair.getKey().toString().equalsIgnoreCase(currentState)) { - return lifecycleStates.get(pair.getKey().toString()); - } - it.remove(); - } - return null; - } - - private boolean getMatchingNextState(Set proceedingStates, String nextState) { - - for (String state: proceedingStates) { - if (state.equalsIgnoreCase(nextState)) { - return true; - } - } - return false; - } -} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/State.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/State.java index e09b070c19..cc54af2daa 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/State.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/State.java @@ -11,9 +11,21 @@ public class State { private Set proceedingStates; private String stateName; + private String permission; + private List allowedActions; + private boolean isAppUpdatable; + private boolean isAppInstallable; + private boolean isInitialState; + private boolean isEndState; - public State(String stateName, List states) { + public State(String stateName, List states, String permission, boolean isAppUpdatable, + boolean isAppInstallable, boolean isInitialState, boolean isEndState) { this.stateName = stateName; + this.permission = permission; + this.isAppUpdatable=isAppUpdatable; + this.isAppInstallable=isAppInstallable; + this.isInitialState=isInitialState; + this.isEndState=isEndState; if (states != null && !states.isEmpty()) { proceedingStates = new HashSet<>(states); } @@ -27,4 +39,14 @@ public class State { return proceedingStates; } + public String getPermission(){ return permission;} + + public boolean getIsAppUpdatable(){ return isAppUpdatable;} + + public boolean getIsAppInstallable(){ return isAppInstallable;} + + public boolean getIsInitialState(){ return isInitialState;} + + public boolean getIsEndState(){ return isEndState;} + } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/config/LifecycleState.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/config/LifecycleState.java index c6682e93e9..7e97175470 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/config/LifecycleState.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/lifecycle/config/LifecycleState.java @@ -3,16 +3,22 @@ package org.wso2.carbon.device.application.mgt.core.lifecycle.config; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; import java.util.List; /** * This class represents the lifecycle state config */ +@XmlRootElement(name = "LifecycleState") public class LifecycleState { private String name; - + private String permission; private List proceedingStates; + private boolean isAppInstallable; + private boolean isAppUpdatable; + private boolean isInitialState; + private boolean isEndState; @XmlAttribute(name = "name") public String getName() { @@ -32,4 +38,50 @@ public class LifecycleState { public void setProceedingStates(List proceedingStates) { this.proceedingStates = proceedingStates; } + + @XmlElement(name = "Permission") + public String getPermission() { + return permission; + } + + public void setPermission(String permission) { + this.permission = permission; + } + + @XmlElement(name = "IsAppInstallable") + public boolean isAppInstallable() { + return isAppInstallable; + } + + public void setAppInstallable(boolean isAppInstallable) { + this.isAppInstallable = isAppInstallable; + } + + @XmlElement(name = "IsAppUpdatable") + public boolean isAppUpdatable() { + return isAppUpdatable; + } + + public void setAppUpdatable(boolean isAppUpdatable) { + this.isAppUpdatable = isAppUpdatable; + } + + @XmlElement(name = "IsInitialState") + public boolean isInitialState() { + return isInitialState; + } + + public void setInitialState(boolean isInitialState) { + this.isInitialState = isInitialState; + } + + @XmlElement(name = "IsEndState") + public boolean isEndState() { + return isEndState; + } + + public void setEndState(boolean isEndState) { + this.isEndState = isEndState; + } + } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java index 0f0901f0b1..3d3da35b87 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/util/ApplicationManagementUtil.java @@ -27,7 +27,7 @@ import org.wso2.carbon.device.application.mgt.common.services.ReviewManager; import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager; import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; import org.wso2.carbon.device.application.mgt.core.config.Extension; -import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManger; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; import java.lang.reflect.Constructor; @@ -64,10 +64,10 @@ public class ApplicationManagementUtil { return getInstance(extension, ApplicationStorageManager.class); } - public static LifecycleStateManger getLifecycleStateMangerInstance() throws InvalidConfigurationException { + public static LifecycleStateManager getLifecycleStateMangerInstance() throws InvalidConfigurationException { ConfigurationManager configurationManager = ConfigurationManager.getInstance(); Extension extension = configurationManager.getExtension(Extension.Name.LifecycleStateManager); - return getInstance(extension, LifecycleStateManger.class); + return getInstance(extension, LifecycleStateManager.class); } private static T getInstance(Extension extension, Class cls) throws InvalidConfigurationException { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifeCycleStateManagerTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifeCycleStateManagerTest.java new file mode 100644 index 0000000000..7dbbfe3304 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifeCycleStateManagerTest.java @@ -0,0 +1,25 @@ +package org.wso2.carbon.device.application.mgt.core; + +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; +import org.wso2.carbon.device.application.mgt.core.lifecycle.State; +import org.wso2.carbon.device.application.mgt.core.lifecycle.config.LifecycleState; + +import java.util.HashMap; +import java.util.List; + + +public class LifeCycleStateManagerTest extends LifecycleStateManager { + + public void initializeLifeCycleDetails(List states) { + HashMap lifecycleStates = new HashMap<>(); + for (LifecycleState s : states) { + if (s.getProceedingStates() != null) { + s.getProceedingStates().replaceAll(String::toUpperCase); + } + lifecycleStates.put(s.getName().toUpperCase(), new State(s.getName().toUpperCase(), + s.getProceedingStates(), s.getPermission(), s.isAppUpdatable(), s.isAppInstallable(), + s.isInitialState(), s.isEndState())); + } + setLifecycleStates(lifecycleStates); + } +} diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifecycleManagementTest.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifecycleManagementTest.java index b6b3d8b261..7082f29b74 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifecycleManagementTest.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/java/org.wso2.carbon.device.application.mgt.core/LifecycleManagementTest.java @@ -3,9 +3,10 @@ package org.wso2.carbon.device.application.mgt.core; import org.junit.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import org.wso2.carbon.device.application.mgt.common.exception.LifecycleManagementException; import org.wso2.carbon.device.application.mgt.core.config.Configuration; import org.wso2.carbon.device.application.mgt.core.config.ConfigurationManager; -import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManger; +import org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager; import org.wso2.carbon.device.application.mgt.core.lifecycle.config.LifecycleState; import java.util.List; @@ -14,45 +15,70 @@ import java.util.Set; public class LifecycleManagementTest { private List lifecycleStates; - private LifecycleStateManger lifecycleStateManger; + private LifecycleStateManager lifecycleStateManager; private final String CURRENT_STATE = "Approved"; private final String NEXT_STATE = "Published"; private final String BOGUS_STATE = "Removed"; + private final String UPDATABLE_STATE = "Created"; + private final String NON_UPDATABLE_STATE = "Removed"; + private final String INSTALLABLE_STATE = "Published"; + private final String UNINSTALlABLE_STATE = "Removed"; + @BeforeClass - public void init() { + public void init() throws LifecycleManagementException { ConfigurationManager configurationManager = ConfigurationManager.getInstance(); Configuration configuration = configurationManager.getConfiguration(); lifecycleStates = configuration.getLifecycleStates(); - lifecycleStateManger = new LifecycleStateManger(); - lifecycleStateManger.init(lifecycleStates); + lifecycleStateManager = new LifeCycleStateManagerTest(); + ((LifeCycleStateManagerTest) lifecycleStateManager).initializeLifeCycleDetails(lifecycleStates); } @Test public void checkValidNextLifecycleState() { - Set proceedingStates = lifecycleStateManger.getNextLifecycleStates(CURRENT_STATE); + Set proceedingStates = lifecycleStateManager.getNextLifecycleStates(CURRENT_STATE); Assert.assertTrue("Invalid proceeding state of: " + CURRENT_STATE, - proceedingStates.contains(NEXT_STATE.toUpperCase())); + proceedingStates.contains(NEXT_STATE.toUpperCase())); } @Test public void checkInvalidNextLifecycleState() { - Set proceedingStates = lifecycleStateManger.getNextLifecycleStates(CURRENT_STATE); + Set proceedingStates = lifecycleStateManager.getNextLifecycleStates(CURRENT_STATE); Assert.assertFalse("Invalid proceeding state of: " + CURRENT_STATE, - proceedingStates.contains(BOGUS_STATE.toUpperCase())); + proceedingStates.contains(BOGUS_STATE.toUpperCase())); + } + + @Test + public void CheckUpdatableState() { + Boolean isUpdatable = lifecycleStateManager.isUpdatable(UPDATABLE_STATE); + System.out.println(isUpdatable); + Assert.assertTrue("Updatable state: " + UPDATABLE_STATE, isUpdatable); } @Test - public void checkValidStateChange() { - Assert.assertTrue("Invalid state transition from: " + CURRENT_STATE + " to: " + NEXT_STATE, - lifecycleStateManger.isValidStateChange(CURRENT_STATE, NEXT_STATE)); + public void CheckNonUpdatableState() { + Boolean isUpdatable = lifecycleStateManager.isUpdatable(NON_UPDATABLE_STATE); + Assert.assertFalse("Non Updatable state: " + NON_UPDATABLE_STATE, isUpdatable); } @Test - public void checkInvalidStateChange() { - Assert.assertFalse("Invalid state transition from: " + CURRENT_STATE + " to: " + BOGUS_STATE, - lifecycleStateManger.isValidStateChange(CURRENT_STATE, BOGUS_STATE)); + public void CheckInstallableState() { + Boolean isInstallable = lifecycleStateManager.isInstallable(INSTALLABLE_STATE); + Assert.assertTrue("Installable state: " + INSTALLABLE_STATE, isInstallable); + } + + @Test + public void CheckUnInstallableState() { + Boolean isInstallable = lifecycleStateManager.isInstallable(UNINSTALlABLE_STATE); + Assert.assertFalse("UnInstallable state: " + UNINSTALlABLE_STATE, isInstallable); + } + + @Test + public void check() { + Set proceedingStates = lifecycleStateManager.getNextLifecycleStates(CURRENT_STATE); + Assert.assertFalse("Invalid proceeding state of: " + CURRENT_STATE, + proceedingStates.contains(BOGUS_STATE.toUpperCase())); } } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/application-mgt.xml b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/application-mgt.xml index 2665bf13d3..be9209ee92 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/application-mgt.xml +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/test/resources/application-mgt.xml @@ -16,7 +16,6 @@ ~ specific language governing permissions and limitations ~ under the License. --> - @@ -30,54 +29,143 @@ org.wso2.carbon.device.application.mgt.core.impl.ReviewManagerImpl - org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManger + org.wso2.carbon.device.application.mgt.core.lifecycle.LifecycleStateManager org.wso2.carbon.device.application.mgt.core.impl.SubscriptionManagerImpl + + org.wso2.carbon.device.application.mgt.core.impl.ApplicationStorageManagerImpl + + repository/resources/apps/ + 6 + + + + + + + true + true + /device-mgt/applications/life-cycle/create In-Review + /device-mgt/applications/life-cycle/in-review Rejected Approved + /device-mgt/applications/life-cycle/approve Published + Created + /device-mgt/applications/life-cycle/reject - In-Review + Created Removed + true + /device-mgt/applications/life-cycle/publish Unpublished Deprecated + /device-mgt/applications/life-cycle/unpublish + Published + In-Review Removed + /device-mgt/applications/life-cycle/deprecate Removed + In-Review + true + /device-mgt/applications/life-cycle/remove + + true + false + false + + + application_management + device_management + subscription_management + review_management + + true + + + perm:app:review:view + perm:app:review:update + perm:app:publisher:view + perm:app:publisher:update + + + app-mgt + + + /application-mgt + + /pages/error/client-errors/400 + /pages/error/client-errors/401 + /pages/error/client-errors/403 + /pages/error/client-errors/404 + /pages/error/client-errors/405 + /pages/error/client-errors/406 + /pages/error/client-errors/415 + /pages/error/server-errors/500 + /pages/error/default + + + diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json index d7ecb8320f..a5e7d491a9 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/package.json @@ -14,6 +14,7 @@ "antd": "^3.15.0", "react": "^16.8.4", "react-dom": "^16.8.4", + "react-highlight-words": "^0.16.0", "react-router-config": "^5.0.0", "react-router-dom": "latest", "react-scripts": "2.1.8" diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.js index 5cf9be115e..be1c130124 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/App.js @@ -1,19 +1,26 @@ import React from "react"; import "antd/dist/antd.css"; -import { renderRoutes } from "react-router-config"; +import RouteWithSubRoutes from "./components/RouteWithSubRoutes"; +import { + BrowserRouter as Router, + Link, +} from 'react-router-dom'; class App extends React.Component { + routes; constructor(props) { super(props); - this.state = { - route : props.route - } + this.routes = props.routes; } render() { return ( -
- {renderRoutes(this.state.route.routes)} -
+ +
+ {this.routes.map((route) => ( + + ))} +
+
); } diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/RouteWithSubRoutes.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/RouteWithSubRoutes.js new file mode 100644 index 0000000000..c172b28edd --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/components/RouteWithSubRoutes.js @@ -0,0 +1,19 @@ +import React from 'react'; +import {Route} from 'react-router-dom'; +class RouteWithSubRoutes extends React.Component{ + props; + constructor(props){ + super(props); + this.props = props; + } + render() { + return( + ( + + )}/> + ); + } + +} + +export default RouteWithSubRoutes; \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/index.css b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/index.css index 8b45ed5931..fa1cc5934e 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/index.css +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/index.css @@ -1,3 +1,27 @@ .App { padding: 20px; +} + +.ant-layout-header{ + padding: 0; + height: auto; + box-shadow: 0 2px 8px #f0f1f2; +} + +.steps-content { + margin-top: 16px; + border: 1px dashed #e9e9e9; + border-radius: 6px; + background-color: #fafafa; + min-height: 200px; + text-align: center; + padding-top: 80px; +} + +.steps-action { + margin-top: 24px; +} + +.ant-input-affix-wrapper .ant-input{ + min-height: 0; } \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/index.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/index.js index 96931fc788..166528a210 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/index.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/index.js @@ -1,41 +1,39 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import './index.css'; -import App from './App'; import * as serviceWorker from './serviceWorker'; -import { renderRoutes } from "react-router-config"; -import Dashboard from "./pages/dashboard/Dashboard" +import App from "./App"; import Login from "./pages/Login"; -import {BrowserRouter} from "react-router-dom"; +import Dashboard from "./pages/dashboard/Dashboard"; +import Apps from "./pages/dashboard/apps/Apps"; +import AddNewApp from "./pages/dashboard/add-new-app/AddNewApp"; +import './index.css'; + const routes = [ { - component: App, + path: '/publisher/Login', + component: Login + }, + { + path: '/publisher/dashboard', + component: Dashboard, routes: [ { - path: "/publisher", - exact: true, - component: Dashboard, - routes: [ - { - path: "/publisher/a", - component: Login - } - ] + path: '/publisher/dashboard/apps', + component: Apps }, { - path: "/publisher/login", - component: Login + path: '/publisher/dashboard/new-app', + component: AddNewApp } ] } -]; +] + + -ReactDOM.render( - {/* kick it all off with the root route */} - {renderRoutes(routes)} -, document.getElementById('root')); +ReactDOM.render( , document.getElementById('root')); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.js b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.js index 6088af4b6f..7e963d7ef9 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.js +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.publisher.ui/react-app/src/pages/dashboard/Dashboard.js @@ -1,53 +1,45 @@ import React from "react"; -import { Layout, Menu, Breadcrumb } from 'antd'; +import { Layout, Menu, Icon } from 'antd'; const { Header, Content, Footer } = Layout; import styles from './Dashboard.less'; import Logo from "../../../public/images/logo.svg"; -import Login from "../Login"; -import {renderRoutes} from "react-router-config"; -import {NavLink} from "react-router-dom"; +import {Link, NavLink} from "react-router-dom"; +import RouteWithSubRoutes from "../../components/RouteWithSubRoutes" class Dashboard extends React.Component { constructor(props) { super(props); this.state = { - route : props.route + routes : props.routes } - console.log(props); } render() { return (
-
+
+ +
- nav 1 - nav 2 - nav 3 + Apps + Apps + Add New App
- - - Home - List - App - - - Items - + + {this.state.routes.map((route) => ( + + ))} - {/* child routes won't render without this */} - {renderRoutes(this.state.route.routes, { someProp: "these extra props are optional" })} -
Content