Progress on saving & changing URI to include version
This commit is contained in:
parent
efccb76206
commit
5433467c45
|
@ -15,6 +15,13 @@ jobs:
|
|||
env:
|
||||
ENVIRONMENT: dev
|
||||
DOCKER_BUILDKIT: 1
|
||||
COMPOSE_FILE: docker-compose.yml:./optional/docker-db-compose.yml
|
||||
SQL_HOST: docker-mysql
|
||||
SQL_USER: root
|
||||
SQL_PASSWORD: root
|
||||
SQL_DB_DRIVER: com.mysql.cj.jdbc.Driver
|
||||
SQL_CONNECTION_STR: jdbc:mysql://docker-mysql/reso_data_dictionary_1_7?autoReconnect=true&maxReconnects=4
|
||||
CERT_REPORT_FILENAME: RESODataDictionary-1.7.metadata-report.json
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
|
|
|
@ -36,6 +36,8 @@ bin
|
|||
classes
|
||||
.DS_Store
|
||||
*.local
|
||||
/*.sql
|
||||
/*.json
|
||||
nb-configuration.xml
|
||||
.externalToolBuilders
|
||||
maven-eclipse.xml
|
||||
|
|
|
@ -18,7 +18,7 @@ Run the `run.sh`
|
|||
|
||||
## Access the Server
|
||||
|
||||
Assuming you're running the server locally, go to [http://localhost:8080/RESOservice-1.0/$metadata](http://localhost:8080/RESOservice-1.0/$metadata)\
|
||||
Assuming you're running the server locally, go to [http://localhost:8080/core/2.0.0/$metadata](http://localhost:8080/core/2.0.0/$metadata)\
|
||||
Otherwise, you will have to replace `localhost` with the IP of your Docker machine.
|
||||
|
||||
## Running with a different database
|
||||
|
@ -48,7 +48,7 @@ The `docker/docker-builder` file has a line commented out for Windows users, and
|
|||
|
||||
This has not been tested. Anyone wanting to give feedback would be appreciated.
|
||||
|
||||
## BUILD FAILURES
|
||||
## Build Failures
|
||||
|
||||
In the case this happens, and you have fixed the source of the error and need to rebuild everything using the build scripts, you should delete any prior Docker containers.
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ fi
|
|||
|
||||
if gradle build
|
||||
then
|
||||
cp build/libs/RESOservice-1.0.war ./target/
|
||||
cp build/libs/RESOservice-1.0.war ./target/core.war
|
||||
cp RESODataDictionary-1.7.metadata-report.json ./target/
|
||||
else
|
||||
|
||||
|
@ -54,6 +54,7 @@ else
|
|||
exit
|
||||
else
|
||||
mvn package
|
||||
mv ./target/RESOservice-1.0.war ./target/core.war
|
||||
cp RESODataDictionary-1.7.metadata-report.json ./target/
|
||||
fi
|
||||
fi
|
|
@ -307,6 +307,7 @@ public class GenericEntityCollectionProcessor implements EntityCollectionProcess
|
|||
}
|
||||
for (Entity product :productList)
|
||||
{
|
||||
// The getValue should already be a String, so the toString should just pass it through, while making the following assignment simple.
|
||||
String key = product.getProperty(primaryFieldName).getValue().toString();
|
||||
HashMap<String, Object> enumValues = entities.get(key);
|
||||
CommonDataProcessing.setEntityEnums(enumValues,product,enumFields);
|
||||
|
|
|
@ -32,10 +32,7 @@ import org.slf4j.LoggerFactory;
|
|||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import static org.reso.service.servlet.RESOservlet.resourceLookup;
|
||||
|
@ -102,12 +99,23 @@ public class GenericEntityProcessor implements EntityProcessor
|
|||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||
}
|
||||
|
||||
protected Entity getData(EdmEntitySet edmEntitySet, List<UriParameter> keyPredicates, ResourceInfo resource) throws ODataApplicationException {
|
||||
|
||||
/**
|
||||
* Reads data from a resource and returns it as a HashMap
|
||||
* @param keyPredicates
|
||||
* @param resource
|
||||
* @return
|
||||
*/
|
||||
private HashMap<String,Object> getDataToHash(List<UriParameter> keyPredicates, ResourceInfo resource)
|
||||
{
|
||||
return CommonDataProcessing.translateEntityToMap(this.getData(null, keyPredicates, resource));
|
||||
}
|
||||
|
||||
protected Entity getData(EdmEntitySet edmEntitySet, List<UriParameter> keyPredicates, ResourceInfo resource) {
|
||||
ArrayList<FieldInfo> fields = resource.getFieldList();
|
||||
|
||||
Entity product = null;
|
||||
|
||||
Map<String, String> properties = System.getenv();
|
||||
List<FieldInfo> enumFields = CommonDataProcessing.gatherEnumFields(resource);
|
||||
|
||||
try {
|
||||
|
@ -119,18 +127,21 @@ public class GenericEntityProcessor implements EntityProcessor
|
|||
// Result set get the result of the SQL query
|
||||
String queryString = null;
|
||||
|
||||
for (final UriParameter key : keyPredicates)
|
||||
if (null!=keyPredicates)
|
||||
{
|
||||
// key
|
||||
String keyName = key.getName(); // .toLowerCase();
|
||||
String keyValue = key.getText();
|
||||
if (sqlCriteria==null)
|
||||
for (final UriParameter key : keyPredicates)
|
||||
{
|
||||
sqlCriteria = keyName + " = " + keyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlCriteria = sqlCriteria + " and " + keyName + " = " + keyValue;
|
||||
// key
|
||||
String keyName = key.getName(); // .toLowerCase();
|
||||
String keyValue = key.getText();
|
||||
if (sqlCriteria==null)
|
||||
{
|
||||
sqlCriteria = keyName + " = " + keyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlCriteria = sqlCriteria + " and " + keyName + " = " + keyValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,22 +224,23 @@ public class GenericEntityProcessor implements EntityProcessor
|
|||
DeserializerResult result = deserializer.entity(requestInputStream, edmEntityType);
|
||||
Entity requestEntity = result.getEntity();
|
||||
// 2.2 do the creation in backend, which returns the newly created entity
|
||||
//Entity createdEntity = storage.createEntityData(edmEntitySet, requestEntity);
|
||||
HashMap<String, Object> mappedObj = CommonDataProcessing.translateEntityToMap(requestEntity);
|
||||
String primaryFieldName = resource.getPrimaryKeyName();
|
||||
|
||||
List<FieldInfo> enumFields = CommonDataProcessing.gatherEnumFields(resource);
|
||||
ArrayList<Object> enumValues = new ArrayList<>();
|
||||
HashMap<String, Object> enumValues = new HashMap<>();
|
||||
for (FieldInfo field: enumFields)
|
||||
{
|
||||
// We remove all entities that are collections to save to the lookup_value table separately. @TODO: save these values
|
||||
if (field.isCollection())
|
||||
{
|
||||
String fieldName = field.getFieldName();
|
||||
Object value = mappedObj.remove(fieldName);
|
||||
enumValues.add(value);
|
||||
enumValues.put(fieldName, value);
|
||||
}
|
||||
}
|
||||
|
||||
saveData(resource, mappedObj);
|
||||
saveEnumData(resource, enumValues);
|
||||
|
||||
// 3. serialize the response (we have to return the created entity)
|
||||
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
|
||||
|
@ -242,7 +254,8 @@ public class GenericEntityProcessor implements EntityProcessor
|
|||
//4. configure the response object
|
||||
response.setContent(serializedResponse.getContent());
|
||||
response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); }
|
||||
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
|
||||
}
|
||||
|
||||
|
||||
private void saveData(ResourceInfo resource, HashMap<String, Object> mappedObj)
|
||||
|
@ -300,6 +313,75 @@ public class GenericEntityProcessor implements EntityProcessor
|
|||
// Result set get the result of the SQL query
|
||||
}
|
||||
|
||||
private void saveEnumData(ResourceInfo resource, HashMap<String, Object> enumValues)
|
||||
{
|
||||
for (String key: enumValues.keySet() )
|
||||
{
|
||||
Object value = enumValues.get(key);
|
||||
saveEnumData(resource, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save the Enum values for the enumObject for the resource.
|
||||
* lookup_value table:
|
||||
* +--------------------------+------------+------+-----+---------------------+-------------------------------+
|
||||
* | Field | Type | Null | Key | Default | Extra |
|
||||
* +--------------------------+------------+------+-----+---------------------+-------------------------------+
|
||||
* | LookupValueKey | text | YES | | NULL | |
|
||||
* | LookupValueKeyNumeric | bigint(20) | YES | | NULL | |
|
||||
* | ResourceName | text | YES | | NULL | |
|
||||
* | ResourceRecordKey | text | YES | | NULL | |
|
||||
* | ResourceRecordKeyNumeric | bigint(20) | YES | | NULL | |
|
||||
* | LookupKey | text | YES | | NULL | |
|
||||
* | modificationTimestamp | timestamp | NO | | current_timestamp() | on update current_timestamp() |
|
||||
* | FieldName | text | NO | | NULL | |
|
||||
* +--------------------------+------------+------+-----+---------------------+-------------------------------+
|
||||
* @param resource
|
||||
* @param values
|
||||
*/
|
||||
private void saveEnumData(ResourceInfo resource, String lookupEnumField, Object values)
|
||||
{
|
||||
String queryString = "insert into lookup_value";
|
||||
|
||||
/**
|
||||
String value = resultSet.getString("LookupKey");
|
||||
String fieldName = resultSet.getString("FieldName");
|
||||
String resourceRecordKey = resultSet.getString("ResourceRecordKey");
|
||||
*/
|
||||
|
||||
try
|
||||
{
|
||||
Statement statement = connect.createStatement();
|
||||
List<String> columnNames = Arrays.asList("FieldName","LookupKey");
|
||||
|
||||
ArrayList valueArray;
|
||||
|
||||
if (values instanceof ArrayList)
|
||||
{
|
||||
valueArray = (ArrayList) values;
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayList temp = new ArrayList();
|
||||
temp.add(values);
|
||||
valueArray = temp;
|
||||
}
|
||||
|
||||
for (Object value : valueArray)
|
||||
{
|
||||
ArrayList<String> columnValues = new ArrayList(Arrays.asList(lookupEnumField,value.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat)
|
||||
throws ODataApplicationException, ODataLibraryException
|
||||
|
|
|
@ -35,6 +35,13 @@ public class CommonDataProcessing
|
|||
private static final Logger LOG = LoggerFactory.getLogger(CommonDataProcessing.class);
|
||||
private static HashMap<String, List<FieldInfo>> resourceEnumFields = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* This function will return the Enum fields for a given resource.
|
||||
* It returns from the cache if found, otherwise it finds the Enum fields from the Field list and caches it for later use.
|
||||
* @param resource
|
||||
* @return List<FieldInfo> The Enum fields' FieldInfo values
|
||||
*/
|
||||
public static List<FieldInfo> gatherEnumFields(ResourceInfo resource)
|
||||
{
|
||||
String resourceName = resource.getResourceName();
|
||||
|
@ -56,23 +63,35 @@ public class CommonDataProcessing
|
|||
}
|
||||
}
|
||||
|
||||
// Put it in the cache
|
||||
CommonDataProcessing.resourceEnumFields.put(resourceName, enumFields);
|
||||
|
||||
return enumFields;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This will return the value for the field from the result set from the data source.
|
||||
* @param field The field metadata
|
||||
* @param resultSet The data source row
|
||||
* @return A Java Object representing the value. It can be anything, but should be a simple representation for ease of manipulating.
|
||||
* @throws SQLException in case of SQL error from the data source
|
||||
*/
|
||||
public static Object getFieldValueFromRow(FieldInfo field, ResultSet resultSet) throws SQLException
|
||||
{
|
||||
String fieldName = field.getFieldName();
|
||||
Object value = null;
|
||||
// In case of a String
|
||||
if (field.getType().equals(EdmPrimitiveTypeKind.String.getFullQualifiedName()))
|
||||
{
|
||||
value = resultSet.getString(fieldName);
|
||||
}
|
||||
// In case of a DateTime entry
|
||||
else if (field.getType().equals(EdmPrimitiveTypeKind.DateTimeOffset.getFullQualifiedName()))
|
||||
{
|
||||
value = resultSet.getTimestamp(fieldName);
|
||||
}
|
||||
// @TODO: More will have to be added here, ie: Integers, as data comes in, we can extend this easily here.
|
||||
else
|
||||
{
|
||||
LOG.info("Field Name: "+field.getFieldName()+" Field type: "+field.getType());
|
||||
|
@ -81,16 +100,32 @@ public class CommonDataProcessing
|
|||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builds an Entity from the row from the Resource's data source
|
||||
* @param resultSet Data source row result
|
||||
* @param resource The resource we're making an Entity for
|
||||
* @param selectLookup An optional lookup of boolean flags that will only fill in the Entity values for entries with True lookup values
|
||||
* @return An Entity representing the data source row
|
||||
* @throws SQLException in case of SQL error from the data source
|
||||
*/
|
||||
public static Entity getEntityFromRow(ResultSet resultSet, ResourceInfo resource, HashMap<String,Boolean> selectLookup) throws SQLException
|
||||
{
|
||||
String primaryFieldName = resource.getPrimaryKeyName();
|
||||
ArrayList<FieldInfo> fields = resource.getFieldList();
|
||||
|
||||
// Lookup Key for the primary key
|
||||
String lookupKey = null;
|
||||
// We only need to set the entity ID later if we're providing selectLookup and the primary field name is being requested
|
||||
// @TODO: May need different logic here, ie: selectLookup==null || ...
|
||||
if (selectLookup!=null && selectLookup.get(primaryFieldName)!=null)
|
||||
{
|
||||
lookupKey = resultSet.getString(primaryFieldName);
|
||||
}
|
||||
|
||||
// New entity to be populated
|
||||
Entity ent = new Entity();
|
||||
|
||||
for (FieldInfo field : fields)
|
||||
{
|
||||
String fieldName = field.getODATAFieldName();
|
||||
|
@ -98,14 +133,17 @@ public class CommonDataProcessing
|
|||
if ( (selectLookup==null || selectLookup.containsKey(fieldName) ))
|
||||
{
|
||||
value = CommonDataProcessing.getFieldValueFromRow(field, resultSet);
|
||||
// We only load Enums from the lookup_value table. @TODO: This may need revision to accommodate lookups on resource tables
|
||||
if (field instanceof EnumFieldInfo)
|
||||
{
|
||||
LOG.error("ENUMS currently only handles by values in lookup_value table. One must Define if this uses a key a numeric value.");
|
||||
}
|
||||
// This is Enums that are bit masks, stored on the resource.
|
||||
else if (field.isCollection())
|
||||
{
|
||||
ent.addProperty(new Property(null, fieldName, ValueType.ENUM, value));
|
||||
}
|
||||
// Simply put in primitive values as entity properties.
|
||||
else
|
||||
{
|
||||
ent.addProperty(new Property(null, fieldName, ValueType.PRIMITIVE, value));
|
||||
|
@ -113,6 +151,7 @@ public class CommonDataProcessing
|
|||
}
|
||||
}
|
||||
|
||||
// Set the entity ID if the lookupKey is provided in the select lookups
|
||||
if (lookupKey!=null)
|
||||
{
|
||||
ent.setId(createId(resource.getResourcesName(), lookupKey));
|
||||
|
@ -121,6 +160,16 @@ public class CommonDataProcessing
|
|||
return ent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a HashMap representation of a row from the data source, similar to the above function.
|
||||
* Useful for building a simple Lookup cache, apart from Entities
|
||||
* @param resultSet Data source row result
|
||||
* @param resource The resource we're making an Entity for
|
||||
* @param selectLookup An optional lookup of boolean flags that will only fill in the Entity values for entries with True lookup values
|
||||
* @return A HashMap representing the data source row
|
||||
* @throws SQLException in case of SQL error from the data source
|
||||
*/
|
||||
public static HashMap<String,Object> getObjectFromRow(ResultSet resultSet, ResourceInfo resource, HashMap<String,Boolean> selectLookup) throws SQLException
|
||||
{
|
||||
String primaryFieldName = resource.getPrimaryKeyName();
|
||||
|
@ -150,6 +199,14 @@ public class CommonDataProcessing
|
|||
return ent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For populating entity values Enums based on a potential non-sequential data source query results
|
||||
* @param resultSet Data source row result
|
||||
* @param entities A lookup of HashMap entities to be populated with Enum values
|
||||
* @param enumFields The Enum fields to populate for the resource
|
||||
* @throws SQLException in case of SQL error from the data source
|
||||
*/
|
||||
public static void getEntityValues(ResultSet resultSet,HashMap<String, HashMap<String, Object>> entities, List<FieldInfo> enumFields) throws SQLException
|
||||
{
|
||||
HashMap<String, EnumFieldInfo> enumFieldLookup = new HashMap<>();
|
||||
|
@ -207,20 +264,26 @@ public class CommonDataProcessing
|
|||
}
|
||||
}
|
||||
|
||||
public static void setEntityEnums(HashMap<String, Object> enumValues, Entity entity, List<FieldInfo> enumFields) throws SQLException
|
||||
{
|
||||
HashMap<String,EnumFieldInfo> enumFieldLookup = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Translate the Enum values from a HashMap representation to an Entity representation
|
||||
* @param enumValues The HashMap representation of the Enum values from the data source
|
||||
* @param entity The Entity to populate with Enum values
|
||||
* @param enumFields The Enum fields on the Entity we want values for
|
||||
*/
|
||||
public static void setEntityEnums(HashMap<String, Object> enumValues, Entity entity, List<FieldInfo> enumFields)
|
||||
{
|
||||
for (FieldInfo field: enumFields)
|
||||
{
|
||||
EnumFieldInfo enumField = (EnumFieldInfo) field;
|
||||
String fieldName = enumField.getFieldName();
|
||||
long totalFlagValues = 3;
|
||||
long totalFlagValues = 0;
|
||||
|
||||
if (field.isFlags())
|
||||
{
|
||||
try
|
||||
{
|
||||
// Builds a bit flag representation of the multiple values.
|
||||
Object flagValues = enumValues.get(fieldName);
|
||||
ArrayList<Object> flagsArray = (ArrayList<Object>) flagValues;
|
||||
for (Object flagObj : flagsArray)
|
||||
|
@ -229,18 +292,21 @@ public class CommonDataProcessing
|
|||
totalFlagValues = totalFlagValues + flagLong;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Exception e) // In case of casting error. "Should not happen"
|
||||
{
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// There's many ways to represent Enums
|
||||
if (field.isCollection())
|
||||
{
|
||||
// As a Collection with bit flags
|
||||
if (field.isFlags())
|
||||
{
|
||||
entity.addProperty(new Property(null, fieldName, ValueType.ENUM, totalFlagValues)); // @ToDo: This might not be compatible with anything...
|
||||
}
|
||||
// A collection of Primitive types
|
||||
else
|
||||
{
|
||||
entity.addProperty(new Property(null, fieldName, ValueType.COLLECTION_PRIMITIVE, enumValues.get(fieldName)));
|
||||
|
@ -248,10 +314,12 @@ public class CommonDataProcessing
|
|||
}
|
||||
else
|
||||
{
|
||||
// Single value, bit flag representation
|
||||
if (field.isFlags())
|
||||
{
|
||||
entity.addProperty(new Property(null, fieldName, ValueType.PRIMITIVE, totalFlagValues));
|
||||
}
|
||||
// Single value Primitive
|
||||
else
|
||||
{
|
||||
entity.addProperty(new Property(null, fieldName, ValueType.PRIMITIVE, enumValues.get(fieldName)));
|
||||
|
@ -260,6 +328,12 @@ public class CommonDataProcessing
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates an Entity to a HashMap representation
|
||||
* @param entity The Entity to turn into a HashMap
|
||||
* @return The HashMap representation of the Entity
|
||||
*/
|
||||
public static HashMap<String,Object> translateEntityToMap(Entity entity)
|
||||
{
|
||||
HashMap<String,Object> result = new HashMap<>();
|
||||
|
@ -276,6 +350,13 @@ public class CommonDataProcessing
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads all Resource entries into a List of HashMap representations of the entries. Useful for caching.
|
||||
* @param connect The data source connection
|
||||
* @param resource The Resource to load
|
||||
* @return A List of HashMap representations of the entries
|
||||
*/
|
||||
public static ArrayList<HashMap<String,Object>> loadAllResource(Connection connect, ResourceInfo resource)
|
||||
{
|
||||
ArrayList<FieldInfo> fields = resource.getFieldList();
|
||||
|
@ -312,8 +393,15 @@ public class CommonDataProcessing
|
|||
}
|
||||
|
||||
return productList;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an unique URI identifier for the entity / id
|
||||
* @param entitySetName Name of the Entity set
|
||||
* @param id unique ID of the object
|
||||
* @return unique URI identifier for the entity / id
|
||||
*/
|
||||
private static URI createId(String entitySetName, Object id) {
|
||||
try {
|
||||
return new URI(entitySetName + "('" + id + "')");
|
||||
|
|
|
@ -61,10 +61,10 @@ public class LookupDefinition extends ResourceInfo
|
|||
fieldInfo = new FieldInfo("ModificationTimestamp", EdmPrimitiveTypeKind.DateTimeOffset.getFullQualifiedName());
|
||||
list.add(fieldInfo);
|
||||
|
||||
/**
|
||||
//// Enum Test code
|
||||
EnumFieldInfo enumFieldInfo = new EnumFieldInfo("EnumTest", EdmPrimitiveTypeKind.Int64.getFullQualifiedName());
|
||||
|
||||
/**
|
||||
enumFieldInfo.setLookupName("EnumTest");
|
||||
//enumFieldInfo.setCollection();
|
||||
enumFieldInfo.setFlags();
|
||||
|
|
|
@ -23,6 +23,6 @@
|
|||
|
||||
<servlet-mapping>
|
||||
<servlet-name>RESOservlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
<url-pattern>/2.0.0/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
Loading…
Reference in New Issue