Adding fixed life-cyle related operations for application

feature/appm-store/pbac
megala21 7 years ago
parent 6e912fccfc
commit 41fa1cb524

@ -69,6 +69,13 @@ import java.util.List;
key = "perm:application:create", key = "perm:application:create",
permissions = {"/device-mgt/application/create"} permissions = {"/device-mgt/application/create"}
), ),
@Scope(
name = "Create an Application",
description = "Create an application",
key = "perm:application-mgt:login",
permissions = {"/device-mgt/application-mgt/login"}
)
} }
) )
@Path("/applications") @Path("/applications")
@ -132,6 +139,45 @@ public interface ApplicationManagementAPI {
@QueryParam("searchQuery") String searchQuery @QueryParam("searchQuery") String searchQuery
); );
@GET
@Path("/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation(
consumes = MediaType.APPLICATION_JSON,
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get the application specified by the UUID",
notes = "This will get the application identified by the UUID, if exists",
tags = "Application Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:application:get")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved relevant application.",
response = Application.class),
@ApiResponse(
code = 404,
message = "Application not found"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while getting relevant application.",
response = ErrorResponse.class)
})
Response getApplication(
@ApiParam(
name = "uuid",
value = "UUID of the application",
required = true)
@PathParam("uuid") String uuid
);
@POST @POST
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ -157,7 +203,8 @@ public interface ApplicationManagementAPI {
@ApiResponse( @ApiResponse(
code = 304, code = 304,
message = "Not Modified. \n " + message = "Not Modified. \n " +
"Empty body because the client already has the latest version of the requested resource."), "Empty body because the client already has the latest version of the requested "
+ "resource."),
@ApiResponse( @ApiResponse(
code = 500, code = 500,
message = "Internal Server Error. \n Error occurred while getting the application list.", message = "Internal Server Error. \n Error occurred while getting the application list.",
@ -179,7 +226,12 @@ public interface ApplicationManagementAPI {
httpMethod = "PUT", httpMethod = "PUT",
value = "Change the life cycle state of the application", value = "Change the life cycle state of the application",
notes = "This will change the life-cycle state of the application", notes = "This will change the life-cycle state of the application",
tags = "Application Management" tags = "Application Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:application-mgt:login")
})
}
) )
@ApiResponses( @ApiResponses(
value = { value = {
@ -213,7 +265,12 @@ public interface ApplicationManagementAPI {
value = "Change the life cycle state of the application", value = "Change the life cycle state of the application",
notes = "This will retrieve the next life cycle states of the application based on the user and the " notes = "This will retrieve the next life cycle states of the application based on the user and the "
+ "current state", + "current state",
tags = "Application Management" tags = "Application Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:application-mgt:login")
})
}
) )
@ApiResponses( @ApiResponses(
value = { value = {
@ -226,7 +283,7 @@ public interface ApplicationManagementAPI {
message = "Internal Server Error. \n Error occurred while getting the life-cycle states.", message = "Internal Server Error. \n Error occurred while getting the life-cycle states.",
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
Response getLifeCycleStates( Response getNextLifeCycleStates(
@ApiParam( @ApiParam(
name = "UUID", name = "UUID",
value = "Unique identifier of the Application", value = "Unique identifier of the Application",

@ -20,27 +20,36 @@ package org.wso2.carbon.device.application.mgt.api.services.impl;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.api.APIUtil;
import org.wso2.carbon.device.application.mgt.api.services.ApplicationManagementAPI; import org.wso2.carbon.device.application.mgt.api.services.ApplicationManagementAPI;
import org.wso2.carbon.device.application.mgt.common.*; import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationList;
import org.wso2.carbon.device.application.mgt.common.Filter;
import org.wso2.carbon.device.application.mgt.common.User;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager; import org.wso2.carbon.device.application.mgt.common.services.ApplicationManager;
import org.wso2.carbon.device.application.mgt.api.APIUtil; import org.wso2.carbon.device.application.mgt.core.util.Constants;
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
import java.util.Arrays;
import javax.validation.Valid; import javax.validation.Valid;
import javax.ws.rs.*; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
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.Response; import javax.ws.rs.core.Response;
import java.util.Date;
@Produces({"application/json"}) @Produces({"application/json"})
@Consumes({"application/json"}) @Consumes({"application/json"})
@Path("/applications") @Path("/applications")
public class ApplicationManagementAPIImpl implements ApplicationManagementAPI { public class ApplicationManagementAPIImpl implements ApplicationManagementAPI {
public static final int DEFAULT_LIMIT = 20; private static final int DEFAULT_LIMIT = 20;
public static final String APPLICATION_UPLOAD_EXTENSION = "ApplicationUploadExtension";
private static Log log = LogFactory.getLog(ApplicationManagementAPIImpl.class); private static Log log = LogFactory.getLog(ApplicationManagementAPIImpl.class);
@GET @GET
@ -71,20 +80,39 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI{
@Path("/{uuid}") @Path("/{uuid}")
public Response getApplication(@PathParam("uuid") String uuid) { public Response getApplication(@PathParam("uuid") String uuid) {
ApplicationManager applicationManager = APIUtil.getApplicationManager(); ApplicationManager applicationManager = APIUtil.getApplicationManager();
return null; try {
Application application = applicationManager.getApplication(uuid);
if (application == null) {
return Response.status(Response.Status.NOT_FOUND)
.entity("Application with UUID " + uuid + " not found").build();
}
return Response.status(Response.Status.OK).entity(application).build();
} catch (ApplicationManagementException e) {
log.error("Error occurred while getting application with the uuid " + uuid, e);
return APIUtil.getResponse(e, Response.Status.INTERNAL_SERVER_ERROR);
}
} }
@PUT @PUT
@Consumes("application/json") @Consumes("application/json")
@Path("/{uuid}/lifecycle") @Path("/{uuid}/lifecycle")
public Response changeLifecycleState(@PathParam("uuid") String applicationUUID, @QueryParam("state") String state) { public Response changeLifecycleState(@PathParam("uuid") String applicationUUID,
@QueryParam("state") String state) {
ApplicationManager applicationManager = APIUtil.getApplicationManager(); ApplicationManager applicationManager = APIUtil.getApplicationManager();
if (!Arrays.asList(Constants.LIFE_CYCLES).contains(state)) {
log.warn("Provided lifecycle state " + state + " is not valid. Please select one from"
+ Arrays.toString(Constants.LIFE_CYCLES));
return Response.status(Response.Status.BAD_REQUEST)
.entity("Provided lifecycle state " + state + " is not valid. Please select one from "
+ Arrays.toString(Constants.LIFE_CYCLES)).build();
}
try { try {
applicationManager.changeLifecycle(applicationUUID, state); applicationManager.changeLifecycle(applicationUUID, state);
} catch (ApplicationManagementException e) { } catch (ApplicationManagementException e) {
String msg = "Error occurred while changing the lifecycle of application: " + applicationUUID; String msg = "Error occurred while changing the lifecycle of application: " + applicationUUID;
log.error(msg, e); log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).build(); return APIUtil.getResponse(e, Response.Status.BAD_REQUEST);
} }
return Response.status(Response.Status.OK) return Response.status(Response.Status.OK)
.entity("Successfully changed the lifecycle state of the application: " + applicationUUID).build(); .entity("Successfully changed the lifecycle state of the application: " + applicationUUID).build();
@ -93,9 +121,21 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI{
@GET @GET
@Path("/{uuid}/lifecycle") @Path("/{uuid}/lifecycle")
@Override @Override
public Response getLifeCycleStates(String applicationUUID) { public Response getNextLifeCycleStates(@PathParam("uuid") String applicationUUID) {
ApplicationManager applicationManager = APIUtil.getApplicationManager(); ApplicationManager applicationManager = APIUtil.getApplicationManager();
try { try {
if (applicationManager.getApplication(applicationUUID) == null) {
if (log.isDebugEnabled()) {
log.debug("Application with the UUID '" + applicationUUID + "' is not found.");
}
return Response.status(Response.Status.NOT_FOUND).entity("Application with the UUID '" +
applicationUUID + "' is not found.").build();
}
if (log.isDebugEnabled()) {
log.debug("Application with UUID '" + applicationUUID + "' is found. Request received for getting "
+ "next life-cycle states for the particular application.");
}
return Response.status(Response.Status.OK).entity(applicationManager.getLifeCycleStates(applicationUUID)) return Response.status(Response.Status.OK).entity(applicationManager.getLifeCycleStates(applicationUUID))
.build(); .build();
} catch (ApplicationManagementException e) { } catch (ApplicationManagementException e) {

@ -59,7 +59,15 @@ public interface ApplicationManager {
*/ */
public ApplicationList getApplications(Filter filter) throws ApplicationManagementException; public ApplicationList getApplications(Filter filter) throws ApplicationManagementException;
void changeLifecycle(String applicationUUID, String lifecycleIdentifier) throws ApplicationManagementException; /**
* To change the lifecycle of the Application.
*
* @param applicationUUID UUID of the Application
* @param lifecycleIdentifier New life-cycle that need to be changed.
* @throws ApplicationManagementException Application Management Exception.
*/
public void changeLifecycle(String applicationUUID, String lifecycleIdentifier) throws
ApplicationManagementException;
/** /**
* To get the next possible life-cycle states for the application. * To get the next possible life-cycle states for the application.
@ -70,4 +78,14 @@ public interface ApplicationManager {
*/ */
public List<LifecycleStateTransition> getLifeCycleStates(String applicationUUID) public List<LifecycleStateTransition> getLifeCycleStates(String applicationUUID)
throws ApplicationManagementException; throws ApplicationManagementException;
/**
* To get Application with the given UUID.
*
* @param uuid UUID of the Application
* @return the Application identified by the UUID
* @throws ApplicationManagementException Application Management Exception.
*/
public Application getApplication(String uuid) throws ApplicationManagementException;
} }

@ -74,7 +74,8 @@
org.apache.axis2.*, org.apache.axis2.*,
org.wso2.carbon.user.core.*, org.wso2.carbon.user.core.*,
org.wso2.carbon.user.api.*, org.wso2.carbon.user.api.*,
org.wso2.carbon.ndatasource.core org.wso2.carbon.ndatasource.core,
org.wso2.carbon
</Import-Package> </Import-Package>
<Export-Package> <Export-Package>
!org.wso2.carbon.device.application.mgt.core.internal.*, !org.wso2.carbon.device.application.mgt.core.internal.*,
@ -158,6 +159,10 @@
<groupId>org.wso2.carbon</groupId> <groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.ndatasource.core</artifactId> <artifactId>org.wso2.carbon.ndatasource.core</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.core</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -18,12 +18,19 @@
*/ */
package org.wso2.carbon.device.application.mgt.core.dao; package org.wso2.carbon.device.application.mgt.core.dao;
import org.wso2.carbon.device.application.mgt.common.*; import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationList;
import org.wso2.carbon.device.application.mgt.common.ApplicationRelease;
import org.wso2.carbon.device.application.mgt.common.Filter;
import org.wso2.carbon.device.application.mgt.common.LifecycleStateTransition;
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/**
* ApplicationDAO is responsible for handling all the Database related operations related with Application Management.
*/
public interface ApplicationDAO { public interface ApplicationDAO {
Application createApplication(Application application) throws ApplicationManagementDAOException; Application createApplication(Application application) throws ApplicationManagementDAOException;
@ -48,11 +55,10 @@ public interface ApplicationDAO {
void deleteTags(int applicationId) throws ApplicationManagementDAOException; void deleteTags(int applicationId) throws ApplicationManagementDAOException;
void changeLifeCycle(LifecycleState lifecycleState) throws ApplicationManagementDAOException;
void addRelease(ApplicationRelease release) throws ApplicationManagementDAOException; void addRelease(ApplicationRelease release) throws ApplicationManagementDAOException;
void changeLifecycle(String applicationUUID, String lifecycleIdentifier) throws ApplicationManagementDAOException; void changeLifecycle(String applicationUUID, String lifecycleIdentifier, String username) throws
ApplicationManagementDAOException;
List<LifecycleStateTransition> getNextLifeCycleStates(String applicationUUID, int tenantId) throws List<LifecycleStateTransition> getNextLifeCycleStates(String applicationUUID, int tenantId) throws
ApplicationManagementDAOException; ApplicationManagementDAOException;

@ -24,6 +24,7 @@ import org.json.JSONException;
import org.wso2.carbon.device.application.mgt.common.Application; import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.Category; import org.wso2.carbon.device.application.mgt.common.Category;
import org.wso2.carbon.device.application.mgt.common.Platform; import org.wso2.carbon.device.application.mgt.common.Platform;
import org.wso2.carbon.device.application.mgt.common.User;
import org.wso2.carbon.device.application.mgt.core.util.JSONUtil; import org.wso2.carbon.device.application.mgt.core.util.JSONUtil;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -54,6 +55,7 @@ public class Util {
application.setScreenshots(JSONUtil.jsonArrayStringToList(rs.getString("SCREENSHOTS"))); application.setScreenshots(JSONUtil.jsonArrayStringToList(rs.getString("SCREENSHOTS")));
application.setCreatedAt(rs.getDate("CREATED_AT")); application.setCreatedAt(rs.getDate("CREATED_AT"));
application.setModifiedAt(rs.getDate("MODIFIED_AT")); application.setModifiedAt(rs.getDate("MODIFIED_AT"));
application.setUser(new User(rs.getString("CREATED_AT"), rs.getInt("TENANT_ID")));
Platform platform = new Platform(); Platform platform = new Platform();
platform.setName(rs.getString("APL_NAME")); platform.setName(rs.getString("APL_NAME"));

@ -20,8 +20,10 @@ package org.wso2.carbon.device.application.mgt.core.dao.impl.application;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.wso2.carbon.device.application.mgt.common.Application; import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.Filter; import org.wso2.carbon.device.application.mgt.common.Filter;
import org.wso2.carbon.device.application.mgt.common.LifecycleStateTransition;
import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException; import org.wso2.carbon.device.application.mgt.common.exception.DBConnectionException;
import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO; import org.wso2.carbon.device.application.mgt.core.dao.ApplicationDAO;
import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl; import org.wso2.carbon.device.application.mgt.core.dao.impl.AbstractDAOImpl;
@ -31,7 +33,9 @@ import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil;
import org.wso2.carbon.device.application.mgt.core.util.JSONUtil; import org.wso2.carbon.device.application.mgt.core.util.JSONUtil;
import java.sql.*; import java.sql.*;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
public abstract class AbstractApplicationDAOImpl extends AbstractDAOImpl implements ApplicationDAO { public abstract class AbstractApplicationDAOImpl extends AbstractDAOImpl implements ApplicationDAO {
@ -182,4 +186,130 @@ public abstract class AbstractApplicationDAOImpl extends AbstractDAOImpl impleme
} }
return count; return count;
} }
@Override
public Application getApplication(String uuid) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting application with the UUID(" + uuid + ") from the database");
}
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
String sql = "";
Application application = null;
try {
conn = this.getDBConnection();
sql += "SELECT APP.*, APL.NAME AS APL_NAME, APL.IDENTIFIER AS APL_IDENTIFIER, "
+ "CAT.ID AS CAT_ID, CAT.NAME AS CAT_NAME FROM APPM_APPLICATION AS APP INNER JOIN APPM_PLATFORM AS "
+ "APL ON APP.PLATFORM_ID = APL.ID INNER JOIN APPM_APPLICATION_CATEGORY AS CAT ON "
+ "APP.APPLICATION_CATEGORY_ID = CAT.ID WHERE UUID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, uuid);
rs = stmt.executeQuery();
if (log.isDebugEnabled()) {
log.debug("Successfully retrieved basic details of the application with the UUID " + uuid);
}
if (rs.next()) {
application = new Application();
//Getting properties
sql = "SELECT * FROM APPM_APPLICATION_PROPERTY WHERE APPLICATION_ID=?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, rs.getInt("ID"));
ResultSet rsProperties = stmt.executeQuery();
//Getting tags
sql = "SELECT * FROM APPM_APPLICATION_TAG WHERE APPLICATION_ID=?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, rs.getInt("ID"));
ResultSet rsTags = stmt.executeQuery();
application = Util.loadApplication(rs, rsProperties, rsTags);
Util.cleanupResources(null, rsProperties);
Util.cleanupResources(null, rsTags);
}
} catch (SQLException e) {
throw new ApplicationManagementDAOException("Error occurred while getting application List", e);
} catch (JSONException e) {
throw new ApplicationManagementDAOException("Error occurred while parsing JSON", e);
} catch (DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while obtaining the DB connection.", e);
} finally {
Util.cleanupResources(stmt, rs);
}
return application;
}
@Override
public void changeLifecycle(String applicationUUID, String lifecycleIdentifier, String userName) throws
ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Change Life cycle status change " + lifecycleIdentifier + "request received to the DAO "
+ "level for the application with " + "the UUID '" + applicationUUID + "' from the user "
+ userName);
}
Connection conn;
PreparedStatement stmt = null;
try {
conn = this.getDBConnection();
String sql = "UPDATE APPM_APPLICATION SET "
+ "LIFECYCLE_STATE_ID = (SELECT ID FROM APPM_LIFECYCLE_STATE WHERE IDENTIFIER = ?), "
+ "LIFECYCLE_STATE_MODIFIED_BY = ?, LIFECYCLE_STATE_MODIFIED_AT = ? WHERE UUID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, lifecycleIdentifier);
stmt.setString(2, userName);
stmt.setDate(3, new Date(System.currentTimeMillis()));
stmt.setString(4, applicationUUID);
stmt.executeUpdate();
} catch (DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while obtaining the DB connection.", e);
} catch (SQLException e) {
throw new ApplicationManagementDAOException(
"Error occurred while changing lifecycle of application: " + applicationUUID + " to: "
+ lifecycleIdentifier + " state.", e);
} finally {
Util.cleanupResources(stmt, null);
}
}
@Override
public List<LifecycleStateTransition> getNextLifeCycleStates(String applicationUUID, int tenantId)
throws ApplicationManagementDAOException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
String sql = "SELECT STATE.NAME, TRANSITION.DESCRIPTION, TRANSITION.PERMISSION FROM ( SELECT * FROM "
+ "APPM_LIFECYCLE_STATE ) STATE RIGHT JOIN (SELECT * FROM APPM_LIFECYCLE_STATE_TRANSITION WHERE "
+ "INITIAL_STATE = (SELECT LIFECYCLE_STATE_ID FROM APPM_APPLICATION WHERE UUID = ?)) "
+ "TRANSITION ON TRANSITION.NEXT_STATE = STATE.ID";
try {
connection = this.getDBConnection();
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, applicationUUID);
resultSet = preparedStatement.executeQuery();
List<LifecycleStateTransition> lifecycleStateTransitions = new ArrayList<>();
while(resultSet.next()) {
LifecycleStateTransition lifecycleStateTransition = new LifecycleStateTransition();
lifecycleStateTransition.setDescription(resultSet.getString(2));
lifecycleStateTransition.setNextState(resultSet.getString(1));
lifecycleStateTransition.setPermission(resultSet.getString(3));
lifecycleStateTransitions.add(lifecycleStateTransition);
}
return lifecycleStateTransitions;
} catch (DBConnectionException e) {
throw new ApplicationManagementDAOException("Error while getting the DBConnection for getting the life "
+ "cycle states for the application with the UUID : " + applicationUUID, e);
} catch (SQLException e) {
throw new ApplicationManagementDAOException("SQL exception while executing the query '" + sql + "'.", e);
} finally {
Util.cleanupResources(preparedStatement, resultSet);
}
}
} }

@ -42,49 +42,6 @@ public class H2ApplicationDAOImpl extends AbstractApplicationDAOImpl {
private static final Log log = LogFactory.getLog(H2ApplicationDAOImpl.class); private static final Log log = LogFactory.getLog(H2ApplicationDAOImpl.class);
@Override
public void changeLifecycle(String applicationUUID, String lifecycleIdentifier) throws ApplicationManagementDAOException {
}
@Override
public List<LifecycleStateTransition> getNextLifeCycleStates(String applicationUUID, int tenantId)
throws ApplicationManagementDAOException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
String sql = "SELECT STATE.NAME, TRANSITION.DESCRIPTION, TRANSITION.PERMISSION FROM ( SELECT * FROM "
+ "APPM_LIFECYCLE_STATE ) STATE RIGHT JOIN (SELECT * FROM APPM_LIFECYCLE_STATE_TRANSITION WHERE "
+ "INITIAL_STATE = (SELECT LIFECYCLE_STATE_ID FROM APPM_APPLICATION WHERE UUID = ?)) "
+ "TRANSITION ON TRANSITION.NEXT_STATE = STATE.ID";
try {
connection = this.getDBConnection();
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, applicationUUID);
resultSet = preparedStatement.executeQuery();
List<LifecycleStateTransition> lifecycleStateTransitions = new ArrayList<>();
while(resultSet.next()) {
LifecycleStateTransition lifecycleStateTransition = new LifecycleStateTransition();
lifecycleStateTransition.setDescription(resultSet.getString(2));
lifecycleStateTransition.setNextState(resultSet.getString(1));
lifecycleStateTransition.setPermission(resultSet.getString(3));
lifecycleStateTransitions.add(lifecycleStateTransition);
}
return lifecycleStateTransitions;
} catch (DBConnectionException e) {
throw new ApplicationManagementDAOException("Error while getting the DBConnection for getting the life "
+ "cycle states for the application with the UUID : " + applicationUUID, e);
} catch (SQLException e) {
throw new ApplicationManagementDAOException("SQL exception while executing the query '" + sql + "'.", e);
} finally {
Util.cleanupResources(preparedStatement, resultSet);
}
}
@Override @Override
public ApplicationList getApplications(Filter filter) throws ApplicationManagementDAOException { public ApplicationList getApplications(Filter filter) throws ApplicationManagementDAOException {
@ -173,11 +130,6 @@ public class H2ApplicationDAOImpl extends AbstractApplicationDAOImpl {
return applicationList; return applicationList;
} }
@Override
public Application getApplication(String uuid) throws ApplicationManagementDAOException {
return null;
}
@Override @Override
public int getApplicationId(String uuid) throws ApplicationManagementDAOException { public int getApplicationId(String uuid) throws ApplicationManagementDAOException {
return 0; return 0;
@ -213,11 +165,6 @@ public class H2ApplicationDAOImpl extends AbstractApplicationDAOImpl {
} }
@Override
public void changeLifeCycle(LifecycleState lifecycleState) throws ApplicationManagementDAOException {
}
@Override @Override
public void addRelease(ApplicationRelease release) throws ApplicationManagementDAOException { public void addRelease(ApplicationRelease release) throws ApplicationManagementDAOException {

@ -134,60 +134,6 @@ public class MySQLApplicationDAOImpl extends AbstractApplicationDAOImpl {
return applicationList; return applicationList;
} }
@Override
public Application getApplication(String uuid) throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting application data from the database");
}
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
String sql = "";
Application application = new Application();
try {
conn = this.getConnection();
sql += "SELECT SQL_CALC_FOUND_ROWS APP.*, APL.NAME AS APL_NAME, APL.IDENTIFIER AS APL_IDENTIFIER, ";
sql += "CAT.ID AS CAT_ID, CAT.NAME AS CAT_NAME ";
sql += "FROM APPM_APPLICATION AS APP ";
sql += "INNER JOIN APPM_PLATFORM AS APL ON APP.PLATFORM_ID = APL.ID ";
sql += "INNER JOIN APPM_APPLICATION_CATEGORY AS CAT ON APP.APPLICATION_CATEGORY_ID = CAT.ID ";
sql += "WHERE UUID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, uuid);
rs = stmt.executeQuery();
if (rs.next()) {
//Getting properties
sql = "SELECT * FROM APPM_APPLICATION_PROPERTY WHERE APPLICATION_ID=?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, rs.getInt("ID"));
ResultSet rsProperties = stmt.executeQuery();
//Getting tags
sql = "SELECT * FROM APPM_APPLICATION_TAG WHERE APPLICATION_ID=?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, rs.getInt("ID"));
ResultSet rsTags = stmt.executeQuery();
application = Util.loadApplication(rs, rsProperties, rsTags);
Util.cleanupResources(null, rsProperties);
Util.cleanupResources(null, rsTags);
}
} catch (SQLException e) {
throw new ApplicationManagementDAOException("Error occurred while getting application List", e);
} catch (JSONException e) {
throw new ApplicationManagementDAOException("Error occurred while parsing JSON", e);
} catch (DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while obtaining the DB connection.", e);
} finally {
Util.cleanupResources(stmt, rs);
}
return application;
}
@Override @Override
public void deleteApplication(String uuid) throws ApplicationManagementDAOException { public void deleteApplication(String uuid) throws ApplicationManagementDAOException {
@ -373,40 +319,6 @@ public class MySQLApplicationDAOImpl extends AbstractApplicationDAOImpl {
} }
} }
@Override
public void changeLifecycle(String applicationUUID, String lifecycleIdentifier) throws ApplicationManagementDAOException {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = this.getDBConnection();
String sql = "UPDATE APPM_APPLICATION SET " +
"LIFECYCLE_STATE_ID = (SELECT ID FROM APPM_LIFECYCLE_STATE WHERE IDENTIFIER = ?), " +
"LIFECYCLE_STATE_MODIFIED_BY = ?, " +
"LIFECYCLE_STATE_MODIFIED_AT = ? " +
"WHERE UUID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, lifecycleIdentifier);
stmt.setString(2, "admin");
stmt.setDate(3, new Date(System.currentTimeMillis()));
stmt.setString(4, applicationUUID);
stmt.executeUpdate();
} catch (DBConnectionException e) {
throw new ApplicationManagementDAOException("Error occurred while obtaining the DB connection.", e);
} catch (SQLException e) {
throw new ApplicationManagementDAOException("Error occurred while changing lifecycle of application: " + applicationUUID + " to: " + lifecycleIdentifier + " state.", e);
} finally {
Util.cleanupResources(stmt, rs);
}
}
@Override
public List<LifecycleStateTransition> getNextLifeCycleStates(String applicationUUID, int tenantId)
throws ApplicationManagementDAOException {
return null;
}
@Override @Override
public void deleteTags(int applicationId) throws ApplicationManagementDAOException { public void deleteTags(int applicationId) throws ApplicationManagementDAOException {
@ -429,11 +341,6 @@ public class MySQLApplicationDAOImpl extends AbstractApplicationDAOImpl {
} }
} }
@Override
public void changeLifeCycle(LifecycleState lifecycleState) throws ApplicationManagementDAOException {
}
@Override @Override
public void addRelease(ApplicationRelease release) throws ApplicationManagementDAOException { public void addRelease(ApplicationRelease release) throws ApplicationManagementDAOException {

@ -20,6 +20,7 @@ package org.wso2.carbon.device.application.mgt.core.impl;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.application.mgt.common.Application; import org.wso2.carbon.device.application.mgt.common.Application;
import org.wso2.carbon.device.application.mgt.common.ApplicationList; import org.wso2.carbon.device.application.mgt.common.ApplicationList;
@ -38,16 +39,21 @@ import org.wso2.carbon.device.application.mgt.core.dao.common.DAOFactory;
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException; import org.wso2.carbon.device.application.mgt.core.exception.ApplicationManagementDAOException;
import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException;
import org.wso2.carbon.device.application.mgt.core.exception.ValidationException; import org.wso2.carbon.device.application.mgt.core.exception.ValidationException;
import org.wso2.carbon.device.application.mgt.core.internal.DataHolder;
import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil; import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil;
import org.wso2.carbon.device.application.mgt.core.util.HelperUtil; import org.wso2.carbon.device.application.mgt.core.util.HelperUtil;
import org.wso2.carbon.user.api.UserRealm;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
public class ApplicationManagerImpl implements ApplicationManager { public class ApplicationManagerImpl implements ApplicationManager {
private static final Log log = LogFactory.getLog(ApplicationManagerImpl.class); private static final Log log = LogFactory.getLog(ApplicationManagerImpl.class);
public static final String CREATED = "CREATED"; private static final String CREATED = "CREATED";
@Override @Override
public Application createApplication(Application application) throws ApplicationManagementException { public Application createApplication(Application application) throws ApplicationManagementException {
@ -154,21 +160,45 @@ public class ApplicationManagerImpl implements ApplicationManager {
public ApplicationList getApplications(Filter filter) throws ApplicationManagementException { public ApplicationList getApplications(Filter filter) throws ApplicationManagementException {
try { try {
ConnectionManagerUtil.openConnection(); ConnectionManagerUtil.openDBConnection();
ApplicationDAO applicationDAO = DAOFactory.getApplicationDAO(); ApplicationDAO applicationDAO = DAOFactory.getApplicationDAO();
return applicationDAO.getApplications(filter); return applicationDAO.getApplications(filter);
} finally { } finally {
ConnectionManagerUtil.closeConnection(); ConnectionManagerUtil.closeDBConnection();
} }
} }
@Override @Override
public void changeLifecycle(String applicationUUID, String lifecycleIdentifier) throws ApplicationManagementException { public void changeLifecycle(String applicationUUID, String lifecycleIdentifier) throws
ApplicationManagementException {
boolean isAvailableNextState = false;
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
List<LifecycleStateTransition> nextLifeCycles = getLifeCycleStates(applicationUUID);
for (LifecycleStateTransition lifecycleStateTransition : nextLifeCycles) {
if (log.isDebugEnabled()) {
log.debug("Lifecycle state of the application " + applicationUUID + " can be changed to"
+ lifecycleStateTransition.getNextState());
}
if (lifecycleStateTransition.getNextState().equalsIgnoreCase(lifecycleIdentifier)) {
isAvailableNextState = true;
break;
}
}
if (!isAvailableNextState) {
throw new ApplicationManagementException("User " + userName + " does not have the permission to change "
+ "the lifecycle state of the application " + applicationUUID + " to lifecycle state "
+ lifecycleIdentifier);
}
try { try {
ConnectionManagerUtil.openDBConnection(); ConnectionManagerUtil.beginDBTransaction();
ApplicationDAO applicationDAO = DAOFactory.getApplicationDAO(); ApplicationDAO applicationDAO = DAOFactory.getApplicationDAO();
applicationDAO.changeLifecycle(applicationUUID, lifecycleIdentifier); applicationDAO.changeLifecycle(applicationUUID, lifecycleIdentifier, userName);
ConnectionManagerUtil.commitDBTransaction();
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
throw e;
} finally { } finally {
ConnectionManagerUtil.closeDBConnection(); ConnectionManagerUtil.closeDBConnection();
} }
@ -177,15 +207,109 @@ public class ApplicationManagerImpl implements ApplicationManager {
@Override @Override
public List<LifecycleStateTransition> getLifeCycleStates(String applicationUUID) public List<LifecycleStateTransition> getLifeCycleStates(String applicationUUID)
throws ApplicationManagementException { throws ApplicationManagementException {
try {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
boolean isAdminOrApplicationOwner = isApplicationOwnerOrAdmin(applicationUUID, userName, tenantId);
if (log.isDebugEnabled()) {
log.debug("User " + userName + " in tenant " + tenantId + " is an Admin or Application owner of the "
+ "application " + applicationUUID);
}
try {
ConnectionManagerUtil.openDBConnection(); ConnectionManagerUtil.openDBConnection();
return DAOFactory.getApplicationDAO().getNextLifeCycleStates(applicationUUID, tenantId); List<LifecycleStateTransition> transitions = DAOFactory.getApplicationDAO()
.getNextLifeCycleStates(applicationUUID, tenantId);
List<LifecycleStateTransition> filteredTransitions = new ArrayList<>();
if (log.isDebugEnabled()) {
log.debug("Lifecycle of the application with UUID : " + applicationUUID + " can be changed to "
+ transitions.size() + ". The number may vary according to the permission level of user : "
+ userName + " of tenant " + tenantId);
}
for (LifecycleStateTransition transition : transitions) {
String permission = transition.getPermission();
if (permission != null) {
if (log.isDebugEnabled()) {
log.debug("In order to make the state change to " + transition.getNextState() + " permission "
+ permission + " is required");
}
if (isAuthorized(userName, tenantId, permission)) {
filteredTransitions.add(transition);
} else {
if (log.isDebugEnabled()) {
log.debug("User " + userName + " does not have the permission " + permission + " to "
+ "change the life-cycle state to " + transition.getNextState() + " of the "
+ "application " + applicationUUID);
}
}
} else if (isAdminOrApplicationOwner) {
filteredTransitions.add(transition);
}
}
if (log.isDebugEnabled()) {
log.debug("User " + userName + " can do " + filteredTransitions.size() + " life-cyle state changes "
+ "currently on application with the UUID " + applicationUUID);
}
return filteredTransitions;
} catch (UserStoreException e) {
throw new ApplicationManagementException(
"Userstore exception while checking whether user " + userName + " from tenant " + tenantId
+ " is authorized to do a life-cycle status change in an application ", e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public Application getApplication(String uuid) throws ApplicationManagementException {
try {
ConnectionManagerUtil.openDBConnection();
return DAOFactory.getApplicationDAO().getApplication(uuid);
} finally { } finally {
ConnectionManagerUtil.closeDBConnection(); ConnectionManagerUtil.closeDBConnection();
} }
} }
/**
* To check whether current user is application owner or admin.
*
* @param applicationUUID UUID of the Application.
* @return true if the current user is application owner or admin, unless false.
* @throws ApplicationManagementException Application Management Exception.
*/
private boolean isApplicationOwnerOrAdmin(String applicationUUID, String userName, int tenantId)
throws ApplicationManagementException {
try {
if (isAuthorized(userName, tenantId, CarbonConstants.UI_ADMIN_PERMISSION_COLLECTION)) {
return true;
}
} catch (UserStoreException e) {
throw new ApplicationManagementException("Userstore exception while checking whether user is an admin", e);
} try {
ConnectionManagerUtil.openDBConnection();
Application application = DAOFactory.getApplicationDAO().getApplication(applicationUUID);
return application.getUser().getUserName().equals(userName)
&& application.getUser().getTenantId() == tenantId;
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
/**
* To check whether current user has the permission to do some secured operation.
*
* @param username Name of the User.
* @param tenantId ID of the tenant.
* @param permission Permission that need to be checked.
* @return true if the current user has the permission, otherwise false.
* @throws UserStoreException UserStoreException
*/
private boolean isAuthorized (String username, int tenantId, String permission) throws UserStoreException {
UserRealm userRealm = DataHolder.getInstance().getRealmService().getTenantUserRealm(tenantId);
return userRealm != null && userRealm.getAuthorizationManager() != null && userRealm.getAuthorizationManager()
.isUserAuthorized(MultitenantUtils.getTenantAwareUsername(username),
permission, CarbonConstants.UI_PERMISSION_ACTION);
}
/** /**
* To validate the application * To validate the application
* *
@ -210,7 +334,5 @@ public class ApplicationManagerImpl implements ApplicationManager {
if (application.getPlatform() == null || application.getPlatform().getIdentifier() == null) { if (application.getPlatform() == null || application.getPlatform().getIdentifier() == null) {
throw new ValidationException("Platform identifier cannot be empty"); throw new ValidationException("Platform identifier cannot be empty");
} }
} }
} }

@ -31,11 +31,12 @@ public class Constants {
public static final String PLATFORMS_DEPLOYMENT_DIR_NAME = "platforms"; public static final String PLATFORMS_DEPLOYMENT_DIR_NAME = "platforms";
public static final String PLATFORM_DEPLOYMENT_EXT = ".xml"; public static final String PLATFORM_DEPLOYMENT_EXT = ".xml";
/**
* Database types supported by Application Management.
*/
public static final class DataBaseTypes { public static final class DataBaseTypes {
private DataBaseTypes() { private DataBaseTypes() {
} }
public static final String DB_TYPE_MYSQL = "MySQL"; public static final String DB_TYPE_MYSQL = "MySQL";
public static final String DB_TYPE_ORACLE = "Oracle"; public static final String DB_TYPE_ORACLE = "Oracle";
public static final String DB_TYPE_MSSQL = "Microsoft SQL Server"; public static final String DB_TYPE_MSSQL = "Microsoft SQL Server";
@ -43,4 +44,10 @@ public class Constants {
public static final String DB_TYPE_H2 = "H2"; public static final String DB_TYPE_H2 = "H2";
public static final String DB_TYPE_POSTGRESQL = "PostgreSQL"; public static final String DB_TYPE_POSTGRESQL = "PostgreSQL";
} }
/**
* Lifecycle states of the application life-cycle.
*/
public static final String[] LIFE_CYCLES = {"CREATED", "IN REVIEW", "APPROVED", "REJECTED", "PUBLISHED",
"UNPUBLISHED", "RETIRED"};
} }

@ -67,7 +67,7 @@ CREATE TABLE IF NOT EXISTS APPM_LIFECYCLE_STATE (
INSERT INTO APPM_LIFECYCLE_STATE (NAME, IDENTIFIER, DESCRIPTION) VALUES ('CREATED', 'CREATED', 'Application creation INSERT INTO APPM_LIFECYCLE_STATE (NAME, IDENTIFIER, DESCRIPTION) VALUES ('CREATED', 'CREATED', 'Application creation
initial state'); initial state');
INSERT INTO APPM_LIFECYCLE_STATE (NAME, IDENTIFIER, DESCRIPTION) INSERT INTO APPM_LIFECYCLE_STATE (NAME, IDENTIFIER, DESCRIPTION)
VALUES ('IN REVIEW', 'IN REFVIEW', 'Application is in in-review state'); VALUES ('IN REVIEW', 'IN REVIEW', 'Application is in in-review state');
INSERT INTO APPM_LIFECYCLE_STATE (NAME, IDENTIFIER, DESCRIPTION) INSERT INTO APPM_LIFECYCLE_STATE (NAME, IDENTIFIER, DESCRIPTION)
VALUES ('APPROVED', 'APPROVED', 'State in which Application is approved after reviewing.'); VALUES ('APPROVED', 'APPROVED', 'State in which Application is approved after reviewing.');
INSERT INTO APPM_LIFECYCLE_STATE (NAME, IDENTIFIER, DESCRIPTION) INSERT INTO APPM_LIFECYCLE_STATE (NAME, IDENTIFIER, DESCRIPTION)
@ -139,7 +139,7 @@ CREATE TABLE IF NOT EXISTS `APPM_APPLICATION` (
`LIFECYCLE_STATE_ID` INT NOT NULL, `LIFECYCLE_STATE_ID` INT NOT NULL,
`LIFECYCLE_STATE_MODIFIED_BY` VARCHAR(255) NULL, `LIFECYCLE_STATE_MODIFIED_BY` VARCHAR(255) NULL,
`LIFECYCLE_STATE_MODIFIED_AT` DATETIME NULL, `LIFECYCLE_STATE_MODIFIED_AT` DATETIME NULL,
`TENANT_ID` INT NULL, `TENANT_ID` INT NOT NULL,
`PLATFORM_ID` INT NOT NULL, `PLATFORM_ID` INT NOT NULL,
PRIMARY KEY (`ID`, `APPLICATION_CATEGORY_ID`, `LIFECYCLE_STATE_ID`, `PLATFORM_ID`), PRIMARY KEY (`ID`, `APPLICATION_CATEGORY_ID`, `LIFECYCLE_STATE_ID`, `PLATFORM_ID`),
UNIQUE INDEX `UUID_UNIQUE` (`UUID` ASC), UNIQUE INDEX `UUID_UNIQUE` (`UUID` ASC),

Loading…
Cancel
Save