mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Add api logs user, security fields
This commit is contained in:
@ -42,6 +42,7 @@ import com.kingsrook.qqq.api.model.APILog;
|
|||||||
import com.kingsrook.qqq.api.model.APIVersion;
|
import com.kingsrook.qqq.api.model.APIVersion;
|
||||||
import com.kingsrook.qqq.api.model.actions.GenerateOpenApiSpecInput;
|
import com.kingsrook.qqq.api.model.actions.GenerateOpenApiSpecInput;
|
||||||
import com.kingsrook.qqq.api.model.actions.GenerateOpenApiSpecOutput;
|
import com.kingsrook.qqq.api.model.actions.GenerateOpenApiSpecOutput;
|
||||||
|
import com.kingsrook.qqq.api.model.metadata.APILogMetaDataProvider;
|
||||||
import com.kingsrook.qqq.api.model.metadata.ApiInstanceMetaData;
|
import com.kingsrook.qqq.api.model.metadata.ApiInstanceMetaData;
|
||||||
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
import com.kingsrook.qqq.api.model.metadata.tables.ApiTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
import com.kingsrook.qqq.backend.core.actions.permissions.PermissionsHelper;
|
||||||
@ -85,6 +86,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.branding.QBrandingMetaData;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.session.QUser;
|
||||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleDispatcher;
|
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleDispatcher;
|
||||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleInterface;
|
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleInterface;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
@ -121,6 +123,8 @@ public class QJavalinApiHandler
|
|||||||
|
|
||||||
private static Map<String, Map<String, QTableMetaData>> tableApiNameMap = new HashMap<>();
|
private static Map<String, Map<String, QTableMetaData>> tableApiNameMap = new HashMap<>();
|
||||||
|
|
||||||
|
private static Map<String, Integer> apiLogUserIdCache = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -366,6 +370,8 @@ public class QJavalinApiHandler
|
|||||||
}
|
}
|
||||||
catch(AccessTokenException aae)
|
catch(AccessTokenException aae)
|
||||||
{
|
{
|
||||||
|
LOG.info("Error getting api access token", aae, logPair("clientId", clientId));
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// if the exception has a status code, then return that code and message //
|
// if the exception has a status code, then return that code and message //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -652,10 +658,27 @@ public class QJavalinApiHandler
|
|||||||
{
|
{
|
||||||
if(QContext.getQInstance().getTable(APILog.TABLE_NAME) != null)
|
if(QContext.getQInstance().getTable(APILog.TABLE_NAME) != null)
|
||||||
{
|
{
|
||||||
|
QSession qSession = QContext.getQSession();
|
||||||
|
if(qSession != null)
|
||||||
|
{
|
||||||
|
for(Map.Entry<String, List<Serializable>> entry : CollectionUtils.nonNullMap(qSession.getSecurityKeyValues()).entrySet())
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// put the 1st entry for this key in the api log record //
|
||||||
|
// todo - might need revisited for users with multiple values... e.g., look for the security key in records in the request? or as part of the URL //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(CollectionUtils.nullSafeHasContents(entry.getValue()))
|
||||||
|
{
|
||||||
|
apiLog.withSecurityKeyValue(entry.getKey(), entry.getValue().get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer userId = getApiLogUserId(qSession);
|
||||||
|
apiLog.setApiLogUserId(userId);
|
||||||
|
}
|
||||||
|
|
||||||
InsertInput insertInput = new InsertInput();
|
InsertInput insertInput = new InsertInput();
|
||||||
insertInput.setTableName(APILog.TABLE_NAME);
|
insertInput.setTableName(APILog.TABLE_NAME);
|
||||||
// todo - security fields!!!!!
|
|
||||||
// todo - user!!!!
|
|
||||||
insertInput.setRecords(List.of(apiLog.toQRecord()));
|
insertInput.setRecords(List.of(apiLog.toQRecord()));
|
||||||
new InsertAction().executeAsync(insertInput);
|
new InsertAction().executeAsync(insertInput);
|
||||||
}
|
}
|
||||||
@ -668,6 +691,129 @@ public class QJavalinApiHandler
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static Integer getApiLogUserId(QSession qSession) throws QException
|
||||||
|
{
|
||||||
|
String tableName = APILogMetaDataProvider.TABLE_NAME_API_LOG_USER;
|
||||||
|
|
||||||
|
if(qSession == null)
|
||||||
|
{
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUser qUser = qSession.getUser();
|
||||||
|
if(qUser == null)
|
||||||
|
{
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
String userName = qUser.getFullName();
|
||||||
|
if(!StringUtils.hasContent(userName))
|
||||||
|
{
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if we haven't cached this username to an id, query and/or insert it now //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(!apiLogUserIdCache.containsKey(userName))
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
// first try to get - if it's found, cache it and return it //
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
Integer id = fetchApiLogUserIdFromName(userName);
|
||||||
|
if(id != null)
|
||||||
|
{
|
||||||
|
apiLogUserIdCache.put(userName, id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
// if it wasn't found from a Get, then try an Insert //
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
LOG.debug("Inserting " + tableName + " named " + userName);
|
||||||
|
InsertInput insertInput = new InsertInput();
|
||||||
|
insertInput.setTableName(tableName);
|
||||||
|
QRecord record = new QRecord().withValue("name", userName);
|
||||||
|
|
||||||
|
for(Map.Entry<String, List<Serializable>> entry : CollectionUtils.nonNullMap(qSession.getSecurityKeyValues()).entrySet())
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// put the 1st entry for this key in the api log user record //
|
||||||
|
// todo - might need revisited for users with multiple values... e.g., look for the security key in records in the request? or as part of the URL //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
if(CollectionUtils.nullSafeHasContents(entry.getValue()))
|
||||||
|
{
|
||||||
|
record.withValue(entry.getKey(), entry.getValue().get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
insertInput.setRecords(List.of(record));
|
||||||
|
InsertOutput insertOutput = new InsertAction().execute(insertInput);
|
||||||
|
id = insertOutput.getRecords().get(0).getValueInteger("id");
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// if we got an id, cache & return it //
|
||||||
|
////////////////////////////////////////
|
||||||
|
if(id != null)
|
||||||
|
{
|
||||||
|
apiLogUserIdCache.put(userName, id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// assume this may mean a dupe-key - so - try another fetch below //
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
LOG.debug("Caught error inserting " + tableName + " named " + userName + " - will try to re-fetch", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// if the insert failed, try another fetch (e.g., after a UK violation) //
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
id = fetchApiLogUserIdFromName(userName);
|
||||||
|
if(id != null)
|
||||||
|
{
|
||||||
|
apiLogUserIdCache.put(userName, id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// give up //
|
||||||
|
/////////////
|
||||||
|
LOG.error("Unable to get id for " + tableName + " named " + userName);
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (apiLogUserIdCache.get(userName));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static Integer fetchApiLogUserIdFromName(String name) throws QException
|
||||||
|
{
|
||||||
|
GetInput getInput = new GetInput();
|
||||||
|
getInput.setTableName(APILogMetaDataProvider.TABLE_NAME_API_LOG_USER);
|
||||||
|
getInput.setUniqueKey(Map.of("name", name));
|
||||||
|
GetOutput getOutput = new GetAction().execute(getInput);
|
||||||
|
if(getOutput.getRecord() != null)
|
||||||
|
{
|
||||||
|
return (getOutput.getRecord().getValueInteger("id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -22,15 +22,22 @@
|
|||||||
package com.kingsrook.qqq.api.model;
|
package com.kingsrook.qqq.api.model;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import com.kingsrook.qqq.api.model.metadata.APILogMetaDataProvider;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.exceptions.QRuntimeException;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QField;
|
import com.kingsrook.qqq.backend.core.model.data.QField;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
|
import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
** In addition to the standard/known fields in this entity, you can also add
|
||||||
|
** name/value pairs of security key values - e.g., a clientId field
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class APILog extends QRecordEntity
|
public class APILog extends QRecordEntity
|
||||||
{
|
{
|
||||||
@ -42,6 +49,9 @@ public class APILog extends QRecordEntity
|
|||||||
@QField(isEditable = false)
|
@QField(isEditable = false)
|
||||||
private Instant timestamp;
|
private Instant timestamp;
|
||||||
|
|
||||||
|
@QField(possibleValueSourceName = APILogMetaDataProvider.TABLE_NAME_API_LOG_USER, label = "User")
|
||||||
|
private Integer apiLogUserId;
|
||||||
|
|
||||||
@QField()
|
@QField()
|
||||||
private String method;
|
private String method;
|
||||||
|
|
||||||
@ -63,6 +73,8 @@ public class APILog extends QRecordEntity
|
|||||||
@QField()
|
@QField()
|
||||||
private String responseBody;
|
private String responseBody;
|
||||||
|
|
||||||
|
private Map<String, Serializable> securityKeyValues = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -75,6 +87,24 @@ public class APILog extends QRecordEntity
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Override
|
||||||
|
public QRecord toQRecord() throws QRuntimeException
|
||||||
|
{
|
||||||
|
QRecord qRecord = super.toQRecord();
|
||||||
|
|
||||||
|
for(Map.Entry<String, Serializable> entry : CollectionUtils.nonNullMap(this.securityKeyValues).entrySet())
|
||||||
|
{
|
||||||
|
qRecord.setValue(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (qRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Constructor
|
** Constructor
|
||||||
**
|
**
|
||||||
@ -390,4 +420,81 @@ public class APILog extends QRecordEntity
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for securityKeyValues
|
||||||
|
*******************************************************************************/
|
||||||
|
public Map<String, Serializable> getSecurityKeyValues()
|
||||||
|
{
|
||||||
|
return (this.securityKeyValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for securityKeyValues
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setSecurityKeyValues(Map<String, Serializable> securityKeyValues)
|
||||||
|
{
|
||||||
|
this.securityKeyValues = securityKeyValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for securityKeyValues
|
||||||
|
*******************************************************************************/
|
||||||
|
public APILog withSecurityKeyValues(Map<String, Serializable> securityKeyValues)
|
||||||
|
{
|
||||||
|
this.securityKeyValues = securityKeyValues;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for securityKeyValues
|
||||||
|
*******************************************************************************/
|
||||||
|
public APILog withSecurityKeyValue(String key, Serializable value)
|
||||||
|
{
|
||||||
|
if(this.securityKeyValues == null)
|
||||||
|
{
|
||||||
|
this.securityKeyValues = new HashMap<>();
|
||||||
|
}
|
||||||
|
this.securityKeyValues.put(key, value);
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for apiLogUserId
|
||||||
|
*******************************************************************************/
|
||||||
|
public Integer getApiLogUserId()
|
||||||
|
{
|
||||||
|
return (this.apiLogUserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for apiLogUserId
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setApiLogUserId(Integer apiLogUserId)
|
||||||
|
{
|
||||||
|
this.apiLogUserId = apiLogUserId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for apiLogUserId
|
||||||
|
*******************************************************************************/
|
||||||
|
public APILog withApiLogUserId(Integer apiLogUserId)
|
||||||
|
{
|
||||||
|
this.apiLogUserId = apiLogUserId;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,16 @@ import com.kingsrook.qqq.backend.core.exceptions.QException;
|
|||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.AdornmentType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.FieldAdornment;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.fields.ValueTooLongBehavior;
|
import com.kingsrook.qqq.backend.core.model.metadata.fields.ValueTooLongBehavior;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.Capability;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.Capability;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.UniqueKey;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -42,13 +46,63 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier;
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class APILogMetaDataProvider
|
public class APILogMetaDataProvider
|
||||||
{
|
{
|
||||||
|
public static final String TABLE_NAME_API_LOG = "apiLog";
|
||||||
|
public static final String TABLE_NAME_API_LOG_USER = "apiLogUser";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static void defineAll(QInstance qInstance, String backendName, Consumer<QTableMetaData> backendDetailEnricher) throws QException
|
public static void defineAll(QInstance qInstance, String backendName, Consumer<QTableMetaData> backendDetailEnricher) throws QException
|
||||||
{
|
{
|
||||||
|
defineApiLogUserPvs(qInstance);
|
||||||
defineAPILogTable(qInstance, backendName, backendDetailEnricher);
|
defineAPILogTable(qInstance, backendName, backendDetailEnricher);
|
||||||
|
defineAPILogUserTable(qInstance, backendName, backendDetailEnricher);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static void defineApiLogUserPvs(QInstance instance)
|
||||||
|
{
|
||||||
|
instance.addPossibleValueSource(new QPossibleValueSource()
|
||||||
|
.withName(TABLE_NAME_API_LOG_USER)
|
||||||
|
.withTableName(TABLE_NAME_API_LOG_USER));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static void defineAPILogUserTable(QInstance qInstance, String backendName, Consumer<QTableMetaData> backendDetailEnricher) throws QException
|
||||||
|
{
|
||||||
|
QTableMetaData tableMetaData = new QTableMetaData()
|
||||||
|
.withName(TABLE_NAME_API_LOG_USER)
|
||||||
|
.withLabel("API Log User")
|
||||||
|
.withIcon(new QIcon().withName("person"))
|
||||||
|
.withBackendName(backendName)
|
||||||
|
.withRecordLabelFormat("%s")
|
||||||
|
.withRecordLabelFields("name")
|
||||||
|
.withPrimaryKeyField("id")
|
||||||
|
.withUniqueKey(new UniqueKey("name"))
|
||||||
|
.withField(new QFieldMetaData("id", QFieldType.INTEGER).withIsEditable(false))
|
||||||
|
.withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withIsEditable(false))
|
||||||
|
.withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME).withIsEditable(false))
|
||||||
|
.withField(new QFieldMetaData("name", QFieldType.STRING).withIsRequired(true))
|
||||||
|
.withSection(new QFieldSection("identity", new QIcon().withName("badge"), Tier.T1, List.of("id", "name")))
|
||||||
|
.withSection(new QFieldSection("dates", new QIcon().withName("calendar_month"), Tier.T3, List.of("createDate", "modifyDate")))
|
||||||
|
.withoutCapabilities(Capability.TABLE_INSERT, Capability.TABLE_UPDATE, Capability.TABLE_DELETE);
|
||||||
|
|
||||||
|
if(backendDetailEnricher != null)
|
||||||
|
{
|
||||||
|
backendDetailEnricher.accept(tableMetaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
qInstance.addTable(tableMetaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -59,14 +113,14 @@ public class APILogMetaDataProvider
|
|||||||
private static void defineAPILogTable(QInstance qInstance, String backendName, Consumer<QTableMetaData> backendDetailEnricher) throws QException
|
private static void defineAPILogTable(QInstance qInstance, String backendName, Consumer<QTableMetaData> backendDetailEnricher) throws QException
|
||||||
{
|
{
|
||||||
QTableMetaData tableMetaData = new QTableMetaData()
|
QTableMetaData tableMetaData = new QTableMetaData()
|
||||||
.withName("apiLog")
|
.withName(TABLE_NAME_API_LOG)
|
||||||
.withLabel("API Log")
|
.withLabel("API Log")
|
||||||
.withIcon(new QIcon().withName("data_object"))
|
.withIcon(new QIcon().withName("data_object"))
|
||||||
.withBackendName(backendName)
|
.withBackendName(backendName)
|
||||||
.withRecordLabelFormat("%s")
|
.withRecordLabelFormat("%s")
|
||||||
.withPrimaryKeyField("id")
|
.withPrimaryKeyField("id")
|
||||||
.withFieldsFromEntity(APILog.class)
|
.withFieldsFromEntity(APILog.class)
|
||||||
.withSection(new QFieldSection("identity", new QIcon().withName("badge"), Tier.T1, List.of("id")))
|
.withSection(new QFieldSection("identity", new QIcon().withName("badge"), Tier.T1, List.of("id", "apiLogUserId")))
|
||||||
.withSection(new QFieldSection("request", new QIcon().withName("arrow_upward"), Tier.T2, List.of("method", "version", "path", "queryString", "requestBody")))
|
.withSection(new QFieldSection("request", new QIcon().withName("arrow_upward"), Tier.T2, List.of("method", "version", "path", "queryString", "requestBody")))
|
||||||
.withSection(new QFieldSection("response", new QIcon().withName("arrow_downward"), Tier.T2, List.of("statusCode", "responseBody")))
|
.withSection(new QFieldSection("response", new QIcon().withName("arrow_downward"), Tier.T2, List.of("statusCode", "responseBody")))
|
||||||
.withSection(new QFieldSection("dates", new QIcon().withName("calendar_month"), Tier.T3, List.of("timestamp")))
|
.withSection(new QFieldSection("dates", new QIcon().withName("calendar_month"), Tier.T3, List.of("timestamp")))
|
||||||
|
Reference in New Issue
Block a user