use of datawave.webservice.common.exception.BadRequestException in project datawave by NationalSecurityAgency.
the class MutableMetadataUUIDHandler method process.
@Override
public void process(Connector con, ModificationRequestBase request, Map<String, Set<String>> mutableFieldList, Set<Authorizations> userAuths, String user) throws BadRequestException, AccumuloException, AccumuloSecurityException, TableNotFoundException, ExecutionException {
VoidResponse response = new VoidResponse();
ArrayList<Exception> exceptions = new ArrayList<>();
MetadataHelper mHelper = getMetadataHelper(con);
// Receive DefaultUUIDModificationRequest
DefaultUUIDModificationRequest uuidModReq = DefaultUUIDModificationRequest.class.cast(request);
List<ModificationEvent> events = uuidModReq.getEvents();
for (ModificationEvent event : events) {
List<ModificationOperationImpl> operations = event.getOperations();
for (ModificationOperationImpl operation : operations) {
ResetValues();
OPERATIONMODE mode = operation.getOperationMode();
String columnVisibility = operation.getColumnVisibility();
String oldColumnVisibility = operation.getOldColumnVisibility();
String eventUser = event.getUser();
// check whether this is a security-marking exempt field. Meaning we can pull the marking if not specified
boolean securityMarkingExempt = false;
fieldName = operation.getFieldName();
for (String s : this.getSecurityMarkingExemptFields()) {
if (fieldName.toUpperCase().equals(s)) {
securityMarkingExempt = true;
}
}
// if they are updating, assume the old values should be the same as current
if (OPERATIONMODE.UPDATE.equals(mode) && oldColumnVisibility == null) {
oldColumnVisibility = columnVisibility;
}
try {
if (mHelper.getIndexOnlyFields(mutableFieldList.keySet()).contains(event.getIdType().toUpperCase())) {
throw new IllegalStateException("Cannot perform modification because " + event.getIdType() + " is index only. Please search " + "with a different uuidType to identify the event you wish to modify.");
}
// perform the lookupUUID
EventBase<?, ? extends FieldBase<?>> idEvent = findMatchingEventUuid(event.getId(), event.getIdType(), userAuths, operation);
// extract contents from lookupUUID necessary for modification
List<? extends FieldBase<?>> fields = idEvent.getFields();
if (operation.getOldFieldValue() != null)
oldFieldValue = operation.getOldFieldValue();
if (fields != null) {
// there may be multiple values for a single field
for (FieldBase<?> f : fields) {
if (f.getName().equals(fieldName)) {
fieldCount++;
// if they are doing a replace, we need all the current values, store them
if (operation.getOperationMode().equals(OPERATIONMODE.REPLACE)) {
if (log != null)
log.trace("Adding " + f.getValueString() + ",delete to replaceMap");
replaceMap.put(f.getValueString(), OPERATIONMODE.DELETE);
}
// user sent an oldValue and we found that value or no oldValue
if ((oldFieldValue != null && f.getValueString().equals(oldFieldValue)) || oldFieldValue == null) {
fieldValue = f.getValueString();
if (columnVisibility == null && securityMarkingExempt) {
fieldColumnVisibility = f.getColumnVisibility();
}
}
} else // only if the input didn't supply a security marking AND it is an exempt field
if (f.getName().equalsIgnoreCase(event.getIdType()) && fieldCount < 1 && columnVisibility == null && securityMarkingExempt) {
if (log != null)
log.trace("Using visibility of " + f.getName() + " and setting to " + f.getColumnVisibility());
fieldColumnVisibility = f.getColumnVisibility();
}
}
List<DefaultModificationRequest> modificationRequests = new ArrayList<>();
if (OPERATIONMODE.INSERT.equals(mode) || OPERATIONMODE.UPDATE.equals(mode) || OPERATIONMODE.DELETE.equals(mode)) {
modificationRequests.add(createModificationRequest(idEvent, operation, columnVisibility, oldColumnVisibility, securityMarkingExempt));
} else if (OPERATIONMODE.REPLACE.equals(mode)) {
if (log != null)
log.trace("Adding " + operation.getFieldValue() + ",insert to replaceMap");
replaceMap.put(operation.getFieldValue(), OPERATIONMODE.INSERT);
// create a modification request of delete for each current value and an insert for the new value
for (String s : replaceMap.keySet()) {
ModificationOperation replaceOperation = operation.clone();
replaceOperation.setOperationMode(replaceMap.get(s));
replaceOperation.setFieldValue(s);
oldFieldValue = s;
modificationRequests.add(createModificationRequest(idEvent, replaceOperation, columnVisibility, oldColumnVisibility, securityMarkingExempt));
}
}
if (log != null)
log.trace("modificationRequests= " + modificationRequests);
for (DefaultModificationRequest modReq : modificationRequests) {
try {
if (fieldCount > 1 && (oldFieldValue == null && modReq.getMode() != MODE.INSERT) && !mode.equals(OPERATIONMODE.REPLACE)) {
throw new IllegalStateException("Unable to perform modification. More than one value exists for " + modReq.getFieldName() + ". Please specify the current value you wish to modify in the oldFieldValue field.");
} else if (fieldCount < 1 && modReq.getMode() != MODE.INSERT) {
throw new IllegalStateException("Unable to perform modification. No values exist for " + modReq.getFieldName() + ".");
} else if (columnVisibility == null && !securityMarkingExempt) {
throw new IllegalStateException("Must provide columnVisibility");
} else // submit DefaultModificationRequest
{
log.info("eventUser = " + eventUser + ", event.getUser() = " + event.getUser());
if (log != null)
log.trace("Submitting request to MutableMetadataHandler from MutableMetadataUUIDHandler: " + modReq);
// make sure user isn't null or empty
if (eventUser == null || eventUser.equals("")) {
if (log != null)
log.trace("No user provided for event. Using caller: " + user);
super.process(con, modReq, mutableFieldList, userAuths, user);
} else {
super.process(con, modReq, mutableFieldList, userAuths, event.getUser());
}
}
}// log exceptions that occur for each modification request. Let as many requests work as possible before returning
catch (Exception e) {
if (log != null)
log.error("Modification error", e);
exceptions.add(new Exception(event.getId() + ": " + e.getMessage() + "\n" + modReq));
}
}
modificationRequests.clear();
} else {
throw new IllegalStateException("No event matched " + event.getId());
}
} catch (Exception e) {
if (log != null)
log.error("Modification error", e);
exceptions.add(new Exception(event.getId() + ": " + e.getMessage() + "\n"));
}
}
}
// If any errors occurred, return them in the response to the user
if (!exceptions.isEmpty()) {
for (Exception e : exceptions) {
QueryException qe = new QueryException(DatawaveErrorCode.MODIFICATION_ERROR, e);
response.addException(qe.getBottomQueryException());
}
QueryException e = new QueryException(DatawaveErrorCode.MODIFICATION_ERROR);
throw new BadRequestException(e, response);
}
}
use of datawave.webservice.common.exception.BadRequestException in project datawave by NationalSecurityAgency.
the class QueryExecutorBean method disableTracing.
/**
* <strong>JBossAdministrator or Administrator credentials required.</strong> Disables tracing that was previously enabled using the
* {@link #enableTracing(String, String)} method.
*
* @param queryRegex
* (optional) the query regular expression defining queries to disable tracing
* @param user
* (optional) the user name for which to disable query tracing
* @return datawave.webservice.result.VoidResponse
*
* @HTTP 200 success
* @HTTP 400 if neither queryRegex nor user are specified
* @HTTP 401 if the user does not have Administrative credentials
*/
@GET
@Path("/disableTracing")
@Produces({ "application/xml", "text/xml", "application/json", "text/yaml", "text/x-yaml", "application/x-yaml", "application/x-protobuf", "application/x-protostuff" })
@RolesAllowed({ "Administrator", "JBossAdministrator" })
@Override
public VoidResponse disableTracing(@QueryParam("queryRegex") String queryRegex, @QueryParam("user") String user) {
VoidResponse response = new VoidResponse();
if (queryRegex == null && user == null) {
BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.QUERY_REGEX_OR_USER_REQUIRED);
response.addException(qe);
throw new BadRequestException(qe, response);
} else if (queryRegex == null) {
traceInfos.removeAll(user);
response.addMessage("All query tracing for " + user + " is disabled. Per-query tracing is still possible.");
} else {
traceInfos.remove(user, PatternWrapper.wrap(queryRegex));
response.addMessage("Queries for user " + user + " matching " + queryRegex + " have been disabled. Per-query tracing is still possible.");
}
// Put updated map back in the cache
queryTraceCache.put("traceInfos", traceInfos);
return response;
}
use of datawave.webservice.common.exception.BadRequestException in project datawave by NationalSecurityAgency.
the class QueryExecutorBean method updateQuery.
private void updateQuery(GenericResponse<String> response, RunningQuery runningQuery, String queryLogicName, String query, Date beginDate, Date endDate, String queryAuthorizations, Date expirationDate, Integer pagesize, Integer pageTimeout, Long maxResultsOverride, QueryPersistence persistenceMode, String parameters) throws Exception {
// Find out who/what called this method
Principal p = ctx.getCallerPrincipal();
String userid = p.getName();
Collection<Collection<String>> cbAuths = new HashSet<>();
if (p instanceof DatawavePrincipal) {
DatawavePrincipal dp = (DatawavePrincipal) p;
userid = dp.getShortName();
cbAuths.addAll(dp.getAuthorizations());
}
log.trace(userid + " has authorizations " + cbAuths);
Query q = runningQuery.getSettings();
// validate persistence mode first
if (persistenceMode != null) {
switch(persistenceMode) {
case PERSISTENT:
if (q.getQueryName() == null)
throw new BadRequestQueryException(DatawaveErrorCode.QUERY_NAME_REQUIRED);
break;
case TRANSIENT:
break;
default:
throw new BadRequestQueryException(DatawaveErrorCode.UNKNOWN_PERSISTENCE_MODE, MessageFormat.format("Mode = {0}", persistenceMode));
}
}
// test for any auditable updates
if (query != null || beginDate != null || endDate != null || queryAuthorizations != null) {
// must clone/audit attempt first
Query duplicate = q.duplicate(q.getQueryName());
duplicate.setId(q.getId());
updateQueryParams(duplicate, queryLogicName, query, beginDate, endDate, queryAuthorizations, expirationDate, pagesize, pageTimeout, maxResultsOverride, parameters);
// Fire off an audit prior to updating
AuditType auditType = runningQuery.getLogic().getAuditType(runningQuery.getSettings());
if (!auditType.equals(AuditType.NONE)) {
try {
MultivaluedMap<String, String> queryParameters = new MultivaluedMapImpl<>();
queryParameters.putAll(duplicate.toMap());
// if the user didn't set an audit id, use the query id
if (!queryParameters.containsKey(AuditParameters.AUDIT_ID)) {
queryParameters.putSingle(AuditParameters.AUDIT_ID, q.getId().toString());
}
auditor.audit(queryParameters);
} catch (IllegalArgumentException e) {
log.error("Error validating audit parameters", e);
BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.MISSING_REQUIRED_PARAMETER, e);
response.addException(qe);
throw new BadRequestException(qe, response);
} catch (Exception e) {
QueryException qe = new QueryException(DatawaveErrorCode.QUERY_AUDITING_ERROR, e);
log.error(qe, e);
response.addException(qe.getBottomQueryException());
throw e;
}
}
}
// update the actual running query
updateQueryParams(q, queryLogicName, query, beginDate, endDate, queryAuthorizations, expirationDate, pagesize, pageTimeout, maxResultsOverride, parameters);
// update the persistenceMode post audit
if (persistenceMode != null) {
switch(persistenceMode) {
case PERSISTENT:
persister.update(q);
break;
case TRANSIENT:
persister.remove(q);
break;
}
}
// Put in the cache by id
queryCache.put(q.getId().toString(), runningQuery);
}
use of datawave.webservice.common.exception.BadRequestException in project datawave by NationalSecurityAgency.
the class QueryExecutorBean method planQuery.
/**
* @param queryLogicName
* @param queryParameters
* @return
*/
@POST
@Produces({ "application/xml", "text/xml", "application/json", "text/yaml", "text/x-yaml", "application/x-yaml", "application/x-protobuf", "application/x-protostuff" })
@Path("/{logicName}/plan")
@Interceptors({ RequiredInterceptor.class, ResponseInterceptor.class })
@Timed(name = "dw.query.planQuery", absolute = true)
public GenericResponse<String> planQuery(@Required("logicName") @PathParam("logicName") String queryLogicName, MultivaluedMap<String, String> queryParameters) {
QueryData qd = validateQuery(queryLogicName, queryParameters, null);
GenericResponse<String> response = new GenericResponse<>();
Query q = null;
Connector connection = null;
AccumuloConnectionFactory.Priority priority;
try {
// Default hasResults to true.
response.setHasResults(true);
// by default we will expand the fields but not the values.
boolean expandFields = true;
boolean expandValues = false;
if (queryParameters.containsKey(EXPAND_FIELDS)) {
expandFields = Boolean.valueOf(queryParameters.getFirst(EXPAND_FIELDS));
}
if (queryParameters.containsKey(EXPAND_VALUES)) {
expandValues = Boolean.valueOf(queryParameters.getFirst(EXPAND_VALUES));
}
AuditType auditType = qd.logic.getAuditType(null);
try {
MultivaluedMap<String, String> optionalQueryParameters = new MultivaluedMapImpl<>();
optionalQueryParameters.putAll(qp.getUnknownParameters(queryParameters));
q = persister.create(qd.userDn, qd.dnList, marking, queryLogicName, qp, optionalQueryParameters);
auditType = qd.logic.getAuditType(q);
} finally {
queryParameters.add(PrivateAuditConstants.AUDIT_TYPE, auditType.name());
// on audit if needed, and we are using the index to expand the values
if (expandValues && !auditType.equals(AuditType.NONE)) {
// audit the query before its executed.
try {
try {
List<String> selectors = qd.logic.getSelectors(q);
if (selectors != null && !selectors.isEmpty()) {
queryParameters.put(PrivateAuditConstants.SELECTORS, selectors);
}
} catch (Exception e) {
log.error("Error accessing query selector", e);
}
// if the user didn't set an audit id, use the query id
if (!queryParameters.containsKey(AuditParameters.AUDIT_ID)) {
queryParameters.putSingle(AuditParameters.AUDIT_ID, q.getId().toString());
}
auditor.audit(queryParameters);
} catch (IllegalArgumentException e) {
log.error("Error validating audit parameters", e);
BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.MISSING_REQUIRED_PARAMETER, e);
response.addException(qe);
throw new BadRequestException(qe, response);
} catch (Exception e) {
log.error("Error auditing query", e);
QueryException qe = new QueryException(DatawaveErrorCode.QUERY_AUDITING_ERROR, e);
response.addException(qe);
throw qe;
}
}
}
priority = qd.logic.getConnectionPriority();
Map<String, String> trackingMap = connectionFactory.getTrackingMap(Thread.currentThread().getStackTrace());
addQueryToTrackingMap(trackingMap, q);
accumuloConnectionRequestBean.requestBegin(q.getId().toString());
try {
connection = connectionFactory.getConnection(qd.logic.getConnPoolName(), priority, trackingMap);
} finally {
accumuloConnectionRequestBean.requestEnd(q.getId().toString());
}
Set<Authorizations> calculatedAuths = AuthorizationsUtil.getDowngradedAuthorizations(qp.getAuths(), qd.p);
String plan = qd.logic.getPlan(connection, q, calculatedAuths, expandFields, expandValues);
response.setResult(plan);
return response;
} catch (Throwable t) {
response.setHasResults(false);
/*
* Allow web services to throw their own WebApplicationExceptions
*/
if (t instanceof Error && !(t instanceof TokenMgrError)) {
log.error(t.getMessage(), t);
throw (Error) t;
} else if (t instanceof WebApplicationException) {
log.error(t.getMessage(), t);
throw ((WebApplicationException) t);
} else {
log.error(t.getMessage(), t);
QueryException qe = new QueryException(DatawaveErrorCode.QUERY_PLAN_ERROR, t);
response.addException(qe.getBottomQueryException());
int statusCode = qe.getBottomQueryException().getStatusCode();
throw new DatawaveWebApplicationException(qe, response, statusCode);
}
} finally {
if (connection != null) {
try {
connectionFactory.returnConnection(connection);
} catch (Exception e) {
log.error("Failed to close connection for " + q.getId(), e);
}
}
// close the logic on exception
try {
if (null != qd.logic) {
qd.logic.close();
}
} catch (Exception e) {
log.error("Exception occured while closing query logic; may be innocuous if scanners were running.", e);
}
if (null != connection) {
try {
connectionFactory.returnConnection(connection);
} catch (Exception e) {
log.error("Error returning connection on failed create", e);
}
}
}
}
use of datawave.webservice.common.exception.BadRequestException in project datawave by NationalSecurityAgency.
the class ExtendedQueryExecutorBeanTest method testEnableTracing_NullChecksAndHappyPath.
@Test
public void testEnableTracing_NullChecksAndHappyPath() throws Exception {
// Set local test input
String user = "user";
String queryRegex = "queryRegex";
PowerMock.resetAll();
// Set expectations
expect(traceInfos.containsEntry(user, PatternWrapper.wrap(queryRegex))).andReturn(false);
expect(traceInfos.put(user, PatternWrapper.wrap(queryRegex))).andReturn(true);
traceCache.put("traceInfos", traceInfos);
// Run the test
PowerMock.replayAll();
QueryExecutorBean subject = new QueryExecutorBean();
setInternalState(subject, Multimap.class, traceInfos);
setInternalState(subject, QueryTraceCache.class, traceCache);
setInternalState(subject, QueryMetricFactory.class, new QueryMetricFactoryImpl());
Exception result1 = null;
try {
subject.enableTracing(null, null);
} catch (BadRequestException e) {
result1 = e;
}
VoidResponse result2 = subject.enableTracing(queryRegex, user);
PowerMock.verifyAll();
// Verify results
assertNotNull("Expected a BadRequestException due to null regex and user values", result1);
assertNotNull("Expected a non-null response", result2);
}
Aggregations