Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AppResources Controller Refactor with Integration Testing for OpenTSDB #311

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public DatabaseItemNotFoundException(String errMessage)
super(HttpServletResponse.SC_NOT_FOUND, errMessage);
this.errMessage = errMessage;
}

public DatabaseItemNotFoundException(String errMessage, Throwable cause)
{
super(HttpServletResponse.SC_NOT_FOUND, errMessage, cause);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@

public final class MissingParameterException extends WebAppException
{
/** detailed error msg */
private String errMessage = "";
/** detailed error msg */
private String errMessage = "";

public MissingParameterException(String errMessage)
{
super(HttpServletResponse.SC_BAD_REQUEST, errMessage);
this.errMessage = errMessage;
}
public MissingParameterException(String errMessage)
{
super(HttpServletResponse.SC_BAD_REQUEST, errMessage);
this.errMessage = errMessage;
}

@Override
public int getStatus()
{
return HttpServletResponse.SC_BAD_REQUEST;
}
@Override
public int getStatus()
{
return HttpServletResponse.SC_BAD_REQUEST;
}

@Override
public String getErrMessage()
{
return errMessage;
}
@Override
public String getErrMessage()
{
return errMessage;
}

}
211 changes: 168 additions & 43 deletions opendcs-rest-api/src/main/java/org/opendcs/odcsapi/res/AppResources.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@

package org.opendcs.odcsapi.res;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
Expand All @@ -31,25 +33,30 @@
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import decodes.sql.DbKey;
import decodes.tsdb.CompAppInfo;
import decodes.tsdb.ConstraintException;
import decodes.tsdb.DbIoException;
import decodes.tsdb.NoSuchObjectException;
import decodes.tsdb.TsdbCompLock;
import opendcs.dai.LoadingAppDAI;
import org.opendcs.odcsapi.beans.ApiAppRef;
import org.opendcs.odcsapi.beans.ApiAppStatus;
import org.opendcs.odcsapi.beans.ApiLoadingApp;
import org.opendcs.odcsapi.dao.ApiAppDAO;
import org.opendcs.odcsapi.dao.DbException;
import org.opendcs.odcsapi.errorhandling.ErrorCodes;
import org.opendcs.odcsapi.errorhandling.DatabaseItemNotFoundException;
import org.opendcs.odcsapi.errorhandling.MissingParameterException;
import org.opendcs.odcsapi.errorhandling.WebAppException;
import org.opendcs.odcsapi.hydrojson.DbInterface;
import org.opendcs.odcsapi.util.ApiConstants;
import org.opendcs.odcsapi.util.ApiHttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Resources for editing, monitoring, stopping, and starting processes.
*/
@Path("/")
public final class AppResources
public final class AppResources extends OpenDcsResource
{
private static final Logger LOGGER = LoggerFactory.getLogger(AppResources.class);
private static final String NO_APP_FOUND = "No such app with ID: %s";

@Context private HttpServletRequest request;
@Context private HttpHeaders httpHeaders;

Expand All @@ -59,31 +66,56 @@ public final class AppResources
@RolesAllowed({ApiConstants.ODCS_API_GUEST})
public Response getAppRefs() throws DbException
{
LOGGER.trace("Getting App Refs.");
try (DbInterface dbi = new DbInterface();
ApiAppDAO dao = new ApiAppDAO(dbi))
try (LoadingAppDAI dai = getLegacyDatabase().makeLoadingAppDAO())
{
List<ApiAppRef> ret = dai.listComputationApps(false)
.stream()
.map(AppResources::map)
.collect(Collectors.toList());
return Response.status(HttpServletResponse.SC_OK)
.entity(ret).build();
}
catch (DbIoException ex)
{
ArrayList<ApiAppRef> ret = dao.getAppRefs();
LOGGER.trace("Returning {} apps.", ret.size());
return ApiHttpUtil.createResponse(ret);
throw new DbException("Unable to retrieve apps", ex);
}
}

static ApiAppRef map(CompAppInfo app)
{
ApiAppRef ret = new ApiAppRef();
ret.setAppId(app.getAppId().getValue());
ret.setAppName(app.getAppName());
ret.setAppType(app.getAppType());
ret.setComment(app.getComment());
ret.setLastModified(app.getLastModified());
return ret;
}

@GET
@Path("app")
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({ApiConstants.ODCS_API_GUEST})
public Response getApp(@QueryParam("appid") Long appId)
throws WebAppException, DbException, SQLException
public Response getApp(@QueryParam("appid") Long appId)
throws WebAppException, DbException
{
if (appId == null)
throw new WebAppException(ErrorCodes.MISSING_ID,
"Missing required appid parameter.");
LOGGER.debug("Getting app with id {}", appId);
try (DbInterface dbi = new DbInterface();
ApiAppDAO dao = new ApiAppDAO(dbi))
{
return ApiHttpUtil.createResponse(dao.getApp(appId));
throw new MissingParameterException("Missing required appid parameter.");
}
try (LoadingAppDAI dai = getLegacyDatabase().makeLoadingAppDAO())
{
return Response.status(HttpServletResponse.SC_OK)
.entity(mapLoading(dai.getComputationApp(DbKey.createDbKey(appId)))).build();
}
catch (NoSuchObjectException e)
{
return Response.status(HttpServletResponse.SC_NOT_FOUND)
.entity(String.format(NO_APP_FOUND, appId)).build();
}
catch (DbIoException ex)
{
throw new DbException(String.format(NO_APP_FOUND, appId), ex);
}
}

Expand All @@ -93,48 +125,141 @@ public Response getApp(@QueryParam("appid") Long appId)
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({ApiConstants.ODCS_API_ADMIN, ApiConstants.ODCS_API_USER})
public Response postApp(ApiLoadingApp app)
throws WebAppException, DbException, SQLException
throws DbException
{
LOGGER.debug("Post app received app {} with id {}", app.getAppName(), app.getAppId());
try (DbInterface dbi = new DbInterface();
ApiAppDAO dao = new ApiAppDAO(dbi))
try (LoadingAppDAI dai = getLegacyDatabase().makeLoadingAppDAO())
{
CompAppInfo compApp = map(app);
dai.writeComputationApp(compApp);
return Response.status(HttpServletResponse.SC_CREATED)
.entity(map(compApp))
.build();
}
catch(DbIoException ex)
{
dao.writeApp(app);
return ApiHttpUtil.createResponse(app);
throw new DbException("Unable to store app", ex);
}
}

static CompAppInfo map(ApiLoadingApp app)
{
CompAppInfo ret = new CompAppInfo();
if (app.getAppId() != null)
{
ret.setAppId(DbKey.createDbKey(app.getAppId()));
}
else
{
ret.setAppId(DbKey.NullKey);
}
ret.setAppName(app.getAppName());
ret.setComment(app.getComment());
ret.setLastModified(app.getLastModified());
ret.setProperties(app.getProperties());
ret.setManualEditApp(app.isManualEditingApp());
String appType = app.getProperties().getProperty("appType");
if (appType == null)
{
ret.setProperty("appType", app.getAppType());
}
return ret;
}

@DELETE
@Path("app")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({ApiConstants.ODCS_API_ADMIN, ApiConstants.ODCS_API_USER})
public Response deletApp(@QueryParam("appid") Long appId)
throws WebAppException, DbException, SQLException
public Response deleteApp(@QueryParam("appid") Long appId)
throws DbException, WebAppException
{
LOGGER.debug("Delete app received request to delete app with id {}", appId);

// Use username and password to attempt to connect to the database
try (DbInterface dbi = new DbInterface();
ApiAppDAO dao = new ApiAppDAO(dbi))
if (appId == null)
{
throw new MissingParameterException("Missing required appid parameter.");
}

try (LoadingAppDAI dai = getLegacyDatabase().makeLoadingAppDAO())
{
CompAppInfo app = dai.getComputationApp(DbKey.createDbKey(appId));
if (app == null)
{
throw new DbException(String.format(NO_APP_FOUND, appId));
}
dai.deleteComputationApp(app);
return Response.status(HttpServletResponse.SC_NO_CONTENT)
.entity("appId with ID " + appId + " deleted").build();
}
catch (NoSuchObjectException e)
{
throw new DatabaseItemNotFoundException(String.format(NO_APP_FOUND, appId), e);
}
catch (DbIoException | ConstraintException ex)
{
dao.deleteApp(appId);
return ApiHttpUtil.createResponse("appId with ID " + appId + " deleted");
throw new DbException(String.format(NO_APP_FOUND, appId), ex);
}
}

@GET
@Path("appstat")
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({ApiConstants.ODCS_API_ADMIN, ApiConstants.ODCS_API_USER})
public Response getAppStat() throws DbException
public Response getAppStatus() throws DbException
{
LOGGER.debug("Getting app stats");
try (DbInterface dbi = new DbInterface();
ApiAppDAO dao = new ApiAppDAO(dbi))
List<ApiAppStatus> ret = new ArrayList<>();
try (LoadingAppDAI dai = getLegacyDatabase().makeLoadingAppDAO())
{
return ApiHttpUtil.createResponse(dao.getAppStatus());
for (TsdbCompLock lock : dai.getAllCompProcLocks())
{
ret.add(map(dai, lock));
}
return Response.status(HttpServletResponse.SC_OK)
.entity(ret).build();
}
catch (DbIoException ex)
{
throw new DbException("Unable to retrieve app status", ex);
}
}

static ApiAppStatus map(LoadingAppDAI dai, TsdbCompLock lock) throws DbIoException
{
ApiAppStatus ret = new ApiAppStatus();
ret.setAppId(lock.getAppId().getValue());
ret.setAppName(lock.getAppName());
ret.setHostname(lock.getHost());
ret.setPid((long) lock.getPID());
ret.setHeartbeat(lock.getHeartbeat());
ret.setStatus(lock.getStatus());
if (dai != null)
{
try {
ApiLoadingApp app = mapLoading(dai.getComputationApp(lock.getAppId()));
if (app.getProperties() == null || app.getProperties().getProperty("EventPort") == null)
{
throw new DbIoException("EventPort property not found");
}
ret.setEventPort(Integer.parseInt(app.getProperties().getProperty("EventPort")));
ret.setAppType(app.getAppType());
}
catch (DbIoException | NoSuchObjectException | NumberFormatException ex)
{
throw new DbIoException("Error mapping app status", ex);
}
}
return ret;
}

static ApiLoadingApp mapLoading(CompAppInfo app)
{
ApiLoadingApp ret = new ApiLoadingApp();
ret.setAppId(app.getAppId().getValue());
ret.setAppName(app.getAppName());
ret.setComment(app.getComment());
ret.setLastModified(app.getLastModified());
ret.setManualEditingApp(app.getManualEditApp());
ret.setAppType(app.getAppType());
ret.setProperties(app.getProperties());
return ret;
}

}
Loading
Loading