Added monadic test containers for Certification. Cleaned up code.

This commit is contained in:
Joshua Darnell 2020-03-25 23:34:13 -07:00
parent 2a27c4ab0e
commit a598261d0d
13 changed files with 1046 additions and 730 deletions

Binary file not shown.

View File

@ -29,10 +29,10 @@ import java.util.List;
public class OAuth2HttpClientFactory extends AbstractHttpClientFactory {
final static String EXPIRES_IN = "expires_in";
final static String ACCESS_TOKEN = "access_token";
private static final Logger LOG = LogManager.getLogger(OAuth2HttpClientFactory.class);
HttpClientConnectionManager connectionManager = null;
private String clientId;
private String clientSecret;
private String tokenUri;
@ -40,15 +40,13 @@ public class OAuth2HttpClientFactory extends AbstractHttpClientFactory {
private String accessToken;
private Integer expiresIn;
final static String EXPIRES_IN = "expires_in";
final static String ACCESS_TOKEN = "access_token";
/**
* Creates an OAuth2 client for making HTTP requests using Client Credentials
* @param clientId the client Id of the consumer
*
* @param clientId the client Id of the consumer
* @param clientSecret the client secret of the consumer
* @param tokenUri the token uri of the server to connect to
* @param scope (optional) scope
* @param tokenUri the token uri of the server to connect to
* @param scope (optional) scope
*/
public OAuth2HttpClientFactory(String clientId, String clientSecret, String tokenUri, String scope) {
this.clientId = clientId;
@ -96,7 +94,7 @@ public class OAuth2HttpClientFactory extends AbstractHttpClientFactory {
if (responseData.get(ACCESS_TOKEN) != null) {
accessToken = responseData.get(ACCESS_TOKEN).asText();
}
assert(accessToken != null);
assert (accessToken != null);
if (responseData.get(EXPIRES_IN) != null) {
expiresIn = responseData.get(EXPIRES_IN).asInt();
@ -110,7 +108,7 @@ public class OAuth2HttpClientFactory extends AbstractHttpClientFactory {
@Override
public CloseableHttpClient create(HttpMethod method, URI uri) {
assert(accessToken != null);
assert (accessToken != null);
BasicHeader authHeader = new BasicHeader("Authorization", "Bearer " + accessToken);
List<Header> headers = new ArrayList<>();
@ -126,7 +124,7 @@ public class OAuth2HttpClientFactory extends AbstractHttpClientFactory {
@Override
public void close(HttpClient httpClient) {
try {
connectionManager.shutdown();
if (connectionManager != null) connectionManager.shutdown();
} catch (Exception ex) {
LOG.error(ex.toString());
}

View File

@ -20,14 +20,13 @@ import java.util.List;
* Extends AbstractHttpClientFactory with one that can accept tokens passed in to make requests.
*/
public class TokenHttpClientFactory extends AbstractHttpClientFactory {
String token;
private static final Logger LOG = LogManager.getLogger(TokenHttpClientFactory.class);
String token;
HttpClientConnectionManager connectionManager = null;
/**
* Constructor for use with tokens.
*
* @param token the token to be used for server requests.
*/
public TokenHttpClientFactory(String token) {

View File

@ -7,8 +7,8 @@ Feature: Web API Server 1.0.2 Certification
Background:
Given a RESOScript file was provided
And Client Settings and Parameters were read from the file
And an OData client was successfully created from the given RESOScript
And the OData client uses authorization_code or client_credentials for authentication
And a test environment was successfully created from the given RESOScript
And the test environment uses an authorization_code or client_credentials for authentication
#######################################
@ -16,12 +16,13 @@ Feature: Web API Server 1.0.2 Certification
#######################################
@REQ-WA103-END3 @core @2.4.1 @core-endorsement @metadata
Scenario: REQ-WA103-END3 - Request and Validate Server Metadata
When a GET request is made to the resolved Url in "REQ-WA103-END3"
When XML Metadata are requested from the service root in "ClientSettings_WebAPIURI"
Then the server responds with a status code of 200
And the response is valid XML
And the XML metadata returned by the server are valid
And a default entity container exists for the service root in "ClientSettings_WebAPIURI"
And Edm metadata are requested from the service root in "ClientSettings_WebAPIURI"
Then the server responds with a status code of 200
And the Edm metadata returned by the server are valid
And the metadata contains a valid service document
And the metadata contains the "Parameter_EndpointResource" resource
And the given "Parameter_EndpointResource" resource exists within "Parameter_DD17_WellKnownResourceList"
And the metadata contains at least one resource from "Parameter_WebAPI102_RequiredResourceList"

View File

@ -12,12 +12,9 @@ import org.apache.http.HttpStatus;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.data.ResWrap;
import org.apache.olingo.client.api.domain.ClientEntitySet;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.commons.api.data.EntityCollection;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
@ -25,10 +22,9 @@ import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.reso.commander.Commander;
import org.reso.commander.TestUtils;
import org.reso.models.ClientSettings;
import org.reso.commander.certfication.containers.WebApiTestContainer;
import org.reso.models.Settings;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.sql.Time;
@ -54,85 +50,49 @@ public class WebAPIServer_1_0_2 implements En {
private static final String SHOW_RESPONSES = "showResponses";
private static final boolean showResponses = Boolean.parseBoolean(System.getProperty(SHOW_RESPONSES));
private static Settings settings;
//container to hold retrieved metadata for later comparisons
private static AtomicReference<XMLMetadata> xmlMetadata = new AtomicReference<>();
private static AtomicReference<Edm> edm = new AtomicReference<>();
private String serviceRoot, bearerToken, clientId, clientSecret, authorizationUri, tokenUri, redirectUri, scope;
private String pathToRESOScript;
/*
* Used to store a static instance of the TestContainer class
* Used to store a static instance of the WebApiTestContainer class
*/
private static AtomicReference<TestContainer> container = new AtomicReference<>(new TestContainer());
private static final AtomicReference<WebApiTestContainer> container = new AtomicReference<>(new WebApiTestContainer());
/**
* Entry point to the Web API Server tests
*/
public WebAPIServer_1_0_2() {
/*
* Background
*/
Given("^a RESOScript file was provided$", () -> {
if (pathToRESOScript == null) {
pathToRESOScript = System.getProperty("pathToRESOScript");
if (getTestContainer().getPathToRESOScript() == null) {
getTestContainer().setPathToRESOScript(System.getProperty("pathToRESOScript"));
}
assertNotNull("ERROR: pathToRESOScript must be present in command arguments, see README", pathToRESOScript);
LOG.info("Using RESOScript: " + pathToRESOScript);
assertNotNull("ERROR: pathToRESOScript must be present in command arguments, see README", getTestContainer().getPathToRESOScript());
LOG.info("Using RESOScript: " + getTestContainer().getPathToRESOScript());
});
And("^Client Settings and Parameters were read from the file$", () -> {
if (settings == null) {
settings = Settings.loadFromRESOScript(new File(System.getProperty("pathToRESOScript")));
if (getTestContainer().getSettings() == null) {
getTestContainer().setSettings(Settings.loadFromRESOScript(new File(System.getProperty("pathToRESOScript"))));
}
assertNotNull("ERROR: Settings could not be loaded.", settings);
assertNotNull("ERROR: Settings could not be loaded.", getTestContainer().getSettings());
LOG.info("RESOScript loaded successfully!");
});
Given("^an OData client was successfully created from the given RESOScript$", () -> {
serviceRoot = settings.getClientSettings().get(ClientSettings.WEB_API_URI);
//TODO: add base64 un-encode when applicable
bearerToken = settings.getClientSettings().get(ClientSettings.BEARER_TOKEN);
if (bearerToken != null && bearerToken.length() > 0) {
LOG.info("Bearer token loaded... first 4 characters: " + bearerToken.substring(0, 4));
}
clientId = settings.getClientSettings().get(ClientSettings.CLIENT_IDENTIFICATION);
clientSecret = settings.getClientSettings().get(ClientSettings.CLIENT_SECRET);
authorizationUri = settings.getClientSettings().get(ClientSettings.AUTHORIZATION_URI);
tokenUri = settings.getClientSettings().get(ClientSettings.TOKEN_URI);
redirectUri = settings.getClientSettings().get(ClientSettings.REDIRECT_URI);
scope = settings.getClientSettings().get(ClientSettings.CLIENT_SCOPE);
LOG.info("Service root is: " + serviceRoot);
if (container.get().commander.get() == null) {
//create Commander instance
container.get().commander.set(new Commander.Builder()
.clientId(clientId)
.clientSecret(clientSecret)
.tokenUri(tokenUri)
.scope(scope)
.serviceRoot(serviceRoot)
.bearerToken(bearerToken)
.useEdmEnabledClient(true)
.build());
}
Given("^a test environment was successfully created from the given RESOScript$", () -> {
getTestContainer().initialize();
});
/*
* Ensures that the client either uses Authorization Codes or Client Credentials
*/
And("^the OData client uses authorization_code or client_credentials for authentication$", () -> {
assertNotNull(container.get().commander.get());
And("^the test environment uses an authorization_code or client_credentials for authentication$", () -> {
assertNotNull(getTestContainer().getCommander());
assertTrue("ERROR: Commander must either have a valid Authorization Code or Client Credentials configuration.",
container.get().commander.get().isTokenClient() || (container.get().commander.get().isOAuthClient() && container.get().commander.get().hasValidAuthConfig()));
getTestContainer().getCommander().isTokenClient() || (getTestContainer().getCommander().isOAuthClient() && getTestContainer().getCommander().hasValidAuthConfig()));
if (container.get().commander.get().isTokenClient()) {
if (getTestContainer().getCommander().isTokenClient()) {
LOG.info("Authentication Type: authorization_code");
} else if (container.get().commander.get().isOAuthClient()) {
} else if (getTestContainer().getCommander().isOAuthClient()) {
LOG.info("Authentication Type: client_credentials");
}
});
@ -141,7 +101,7 @@ public class WebAPIServer_1_0_2 implements En {
* REQ-WA103-END2 - validate DataSystem endpoint, if present.
*/
And("^the results match the expected DataSystem JSON schema$", () -> {
if (container.get().responseCode.get() == HttpStatus.SC_OK && container.get().responseData.get() != null) {
if (getTestContainer().getResponseCode() == HttpStatus.SC_OK && getTestContainer().getResponseData() != null) {
try {
JsonSchemaFactory factory = JsonSchemaFactory.getInstance();
InputStream is = Thread.currentThread().getContextClassLoader()
@ -149,7 +109,7 @@ public class WebAPIServer_1_0_2 implements En {
JsonSchema schema = factory.getSchema(is);
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(container.get().responseData.get());
JsonNode node = mapper.readTree(getTestContainer().getResponseData());
if (node.findPath(JSON_VALUE_PATH).size() > 0) {
Set<ValidationMessage> errors = schema.validate(node);
@ -161,7 +121,7 @@ public class WebAPIServer_1_0_2 implements En {
LOG.info("DataSystem response matches reference schema!");
}
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
}
});
@ -170,46 +130,60 @@ public class WebAPIServer_1_0_2 implements En {
* Edm Metadata Validator
*/
And("^the Edm metadata returned by the server are valid$", () -> {
assertNotNull("ERROR: No Entity Data Model (Edm) Exists!", edm.get());
assertNotNull("ERROR: No Entity Data Model (Edm) Exists!", getTestContainer().getEdm());
try {
boolean isValid = container.get().commander.get().validateMetadata(edm.get());
boolean isValid = getTestContainer().getCommander().validateMetadata(getTestContainer().getEdm());
LOG.info("Edm Metadata is " + (isValid ? "valid" : "invalid") + "!");
assertTrue("Edm Metadata at the given service root is not valid! " + serviceRoot, isValid);
assertTrue("Edm Metadata at the given service root is not valid! " + getTestContainer().getServiceRoot(), isValid);
} catch (Exception ex) {
fail("ERROR: could not validate Edm Metadata!\n" + ex.getMessage());
fail("ERROR: could not validate Edm Metadata!\n" + ex.toString());
}
});
/*
* XMLMetadata Validator
* XML Metadata Validator
*/
And("^the XML metadata returned by the server are valid$", () -> {
assertNotNull("ERROR: No Response Data exists to convert to XML Metadata!", container.get().responseData.get());
assertNotNull("ERROR: XML Metadata (EDMX) Exists!", getTestContainer().getXMLMetadata());
try {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(container.get().responseData.get().getBytes());
xmlMetadata.set(container.get().commander.get().getClient().getDeserializer(ContentType.APPLICATION_XML).toMetadata(byteArrayInputStream));
if (showResponses) LOG.info("XML Metadata is \n" + container.get().responseData.get());
boolean isValid = container.get().commander.get().validateMetadata(xmlMetadata.get());
boolean isValid = getTestContainer().getCommander().validateMetadata(getTestContainer().getXMLMetadata());
LOG.info("XML Metadata is " + (isValid ? "valid" : "invalid") + "!");
assertTrue("ERROR: XML Metadata at the given service root is not valid! " + serviceRoot, isValid);
assertTrue("XML Metadata at the given service root is not valid! " + getTestContainer().getServiceRoot(), isValid);
} catch (Exception ex) {
fail("ERROR: could not validate XML Metadata!\n" + ex.getMessage());
fail("ERROR: could not validate XML Metadata!\n" + ex.toString());
}
});
// /*
// * XMLMetadata Validator
// */
// And("^the XML metadata returned by the server are valid$", () -> {
// assertNotNull("ERROR: No Response Data exists to convert to XML Metadata!", getTestContainer().responseData.get());
//
// try {
// ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(getTestContainer().responseData.get().getBytes());
// xmlMetadata.set(getTestContainer().commander.get().getClient().getDeserializer(ContentType.APPLICATION_XML).toMetadata(byteArrayInputStream));
//
// if (showResponses) LOG.info("XML Metadata is: \n" + getTestContainer().responseData.get());
//
// boolean isValid = getTestContainer().commander.get().validateMetadata(getTestContainer().getXmlMetadata());
// LOG.info("XML Metadata is " + (isValid ? "valid" : "invalid") + "!");
// assertTrue("ERROR: XML Metadata at the given service root is not valid! " + serviceRoot, isValid);
// } catch (Exception ex) {
// fail("ERROR: could not validate XML Metadata!\n" + ex.toString());
// }
// });
/*
* REQ-WA103-QR1
*/
And("^the provided \"([^\"]*)\" is returned in \"([^\"]*)\"$", (String parameterUniqueIdValue, String parameterUniqueId) -> {
try {
String expectedValueAsString = Settings.resolveParametersString(parameterUniqueIdValue, settings), resolvedValueAsString = null;
Object resolvedValue = from(container.get().responseData.get()).get(Settings.resolveParametersString(parameterUniqueId, settings));
String expectedValueAsString = Settings.resolveParametersString(parameterUniqueIdValue, getTestContainer().getSettings());
Object resolvedValue = from(getTestContainer().getResponseData()).get(Settings.resolveParametersString(parameterUniqueId, getTestContainer().getSettings()));
//both of the inputs should be present
assertNotNull(expectedValueAsString);
@ -228,7 +202,7 @@ public class WebAPIServer_1_0_2 implements En {
assertEquals("ERROR: the given String value is not equal to the value found on the server!", expectedValueAsString, resolvedValue.toString());
}
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -238,11 +212,11 @@ public class WebAPIServer_1_0_2 implements En {
And("^data are present in fields contained within \"([^\"]*)\"$", (String parameterSelectList) -> {
try {
AtomicInteger numFieldsWithData = new AtomicInteger();
List<String> fieldList = new ArrayList<>(Arrays.asList(Settings.resolveParametersString(parameterSelectList, settings).split(FIELD_SEPARATOR)));
List<String> fieldList = new ArrayList<>(Arrays.asList(Settings.resolveParametersString(parameterSelectList, getTestContainer().getSettings()).split(FIELD_SEPARATOR)));
AtomicInteger numResults = new AtomicInteger();
//iterate over the items and count the number of fields with data to determine whether there are data present
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
if (item != null) {
numResults.getAndIncrement();
fieldList.forEach(field -> {
@ -261,9 +235,9 @@ public class WebAPIServer_1_0_2 implements En {
} else {
LOG.info("Percent Fill: 0% - no fields with data found!");
}
assertTrue("ERROR: no fields with data could be found from the given $select list!",numFieldsWithData.get() > 0);
assertTrue("ERROR: no fields with data could be found from the given $select list!", numFieldsWithData.get() > 0);
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -274,16 +248,16 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^the results contain at most \"([^\"]*)\" records$", (String parameterTopCount) -> {
try {
List<String> items = from(container.get().responseData.get()).getList(JSON_VALUE_PATH);
List<String> items = from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH);
AtomicInteger numResults = new AtomicInteger(items.size());
int topCount = Integer.parseInt(Settings.resolveParametersString(parameterTopCount, settings));
int topCount = Integer.parseInt(Settings.resolveParametersString(parameterTopCount, getTestContainer().getSettings()));
LOG.info("Number of values returned: " + numResults.get() + ", top count is: " + topCount);
assertTrue("ERROR: results count must be greater than zero and less than " + parameterTopCount + "!",
numResults.get() > 0 && numResults.get() <= topCount);
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -294,24 +268,24 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^a GET request is made to the resolved Url in \"([^\"]*)\" with \\$skip=\"([^\"]*)\"$", (String requirementId, String parameterTopCount) -> {
try {
int skipCount = Integer.parseInt(Settings.resolveParametersString(parameterTopCount, settings));
int skipCount = Integer.parseInt(Settings.resolveParametersString(parameterTopCount, getTestContainer().getSettings()));
LOG.info("Skip count is: " + skipCount);
//preserve initial response data for later comparisons
container.get().initialResponseData.set(container.get().responseData.get());
getTestContainer().setInitialResponseData(getTestContainer().getResponseData());
//TODO: convert to OData filter factory
container.get().requestUri.set(Commander.prepareURI(Settings.resolveParameters(settings.getRequestById(requirementId), settings).getUrl()
+ "&" + Commander.ODATA_QUERY_OPTIONS.SKIP +"=" + skipCount));
container.set(executeGetRequest(container.get().requestUri.get(), container.get()));
getTestContainer().setRequestUri(Commander.prepareURI(Settings.resolveParameters(getTestContainer().getSettings().getRequestById(requirementId), getTestContainer().getSettings()).getUrl()
+ "&" + Commander.ODATA_QUERY_OPTIONS.SKIP + "=" + skipCount));
getTestContainer().executePreparedGetRequest();
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
And("^data in the \"([^\"]*)\" fields are different in the second request than in the first$", (String parameterUniqueId) -> {
try {
List<POJONode> l1 = from(container.get().initialResponseData.get()).getJsonObject(JSON_VALUE_PATH);
List<POJONode> l2 = from(container.get().responseData.get()).getJsonObject(JSON_VALUE_PATH);
List<POJONode> l1 = from(getTestContainer().getInitialResponseData()).getJsonObject(JSON_VALUE_PATH);
List<POJONode> l2 = from(getTestContainer().getResponseData()).getJsonObject(JSON_VALUE_PATH);
int combinedCount = l1.size() + l2.size();
Set<POJONode> combined = new LinkedHashSet<>(l1);
@ -325,7 +299,7 @@ public class WebAPIServer_1_0_2 implements En {
assertEquals("ERROR: repeated data found, expected unique data on each page!", combinedCount, combined.size());
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -339,11 +313,12 @@ public class WebAPIServer_1_0_2 implements En {
When("^a GET request is made to the resolved Url in \"([^\"]*)\"$", (String requestId) -> {
try {
//reset local state each time a get request is run
container.get().resetState();
getTestContainer().resetState();
LOG.info("Request ID: " + requestId);
container.get().requestUri.set(Commander.prepareURI(Settings.resolveParameters(settings.getRequestById(requestId), settings).getUrl()));
container.set(executeGetRequest(container.get().requestUri.get(), container.get()));
getTestContainer().setRequestUri(Commander.prepareURI(Settings.resolveParameters(
getTestContainer().getSettings().getRequestById(requestId), getTestContainer().getSettings()).getUrl()));
getTestContainer().executePreparedGetRequest();
} catch (Exception ex) {
LOG.debug("Exception was thrown in " + this.getClass() + ": " + ex.toString());
}
@ -354,13 +329,13 @@ public class WebAPIServer_1_0_2 implements En {
*/
Then("^the server responds with a status code of (\\d+)$", (Integer assertedResponseCode) -> {
try {
LOG.info("Asserted Response Code: " + assertedResponseCode + ", Server Response Code: " + container.get().responseCode);
assertTrue(container.get().responseCode.get() > 0 && assertedResponseCode > 0);
LOG.info("Asserted Response Code: " + assertedResponseCode + ", Server Response Code: " + getTestContainer().getResponseCode());
assertTrue(getTestContainer().getResponseCode() > 0 && assertedResponseCode > 0);
assertEquals("ERROR: asserted response code does not match the one returned from the server!",
assertedResponseCode.intValue(), container.get().responseCode.get().intValue());
assertedResponseCode.intValue(), getTestContainer().getResponseCode().intValue());
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -369,10 +344,10 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^the response is valid XML$", () -> {
try {
assertTrue("ERROR: invalid XML response!", Commander.validateXML(container.get().responseData.get()));
assertTrue("ERROR: invalid XML response!", Commander.validateXML(getTestContainer().getXMLMetadata()));
LOG.info("Response is valid XML!");
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -381,12 +356,13 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^the response is valid JSON$", () -> {
try {
assertTrue("ERROR: invalid JSON response!", TestUtils.isValidJson(container.get().responseData.get()));
assertTrue("ERROR: invalid JSON response!", TestUtils.isValidJson(getTestContainer().getResponseData()));
LOG.info("Response is valid JSON!");
if (showResponses) LOG.info("Response: " + new ObjectMapper().readTree(container.get().responseData.get()).toPrettyString());
if (showResponses)
LOG.info("Response: " + new ObjectMapper().readTree(getTestContainer().getResponseData()).toPrettyString());
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -397,13 +373,13 @@ public class WebAPIServer_1_0_2 implements En {
*/
Then("^the server responds with a status code of (\\d+) if the server headers report OData version \"([^\"]*)\"$", (Integer assertedHttpResponseCode, String assertedODataVersion) -> {
try {
boolean versionsMatch = container.get().serverODataHeaderVersion.get().equals(assertedODataVersion),
responseCodesMatch = container.get().responseCode.get().intValue() == assertedHttpResponseCode.intValue();
boolean versionsMatch = getTestContainer().getServerODataHeaderVersion().equals(assertedODataVersion),
responseCodesMatch = getTestContainer().getResponseCode().intValue() == assertedHttpResponseCode.intValue();
LOG.info("Asserted OData Version: " + assertedODataVersion + ", Server Version: " + container.get().serverODataHeaderVersion.get());
LOG.info("Asserted OData Version: " + assertedODataVersion + ", Server Version: " + getTestContainer().getServerODataHeaderVersion());
if (versionsMatch) {
LOG.info("Asserted Response Code: " + assertedHttpResponseCode + ", Response code: " + container.get().responseCode.get());
LOG.info("Asserted Response Code: " + assertedHttpResponseCode + ", Response code: " + getTestContainer().getResponseCode());
assertTrue("ERROR: asserted response code does not match the one returned from the server!", responseCodesMatch);
}
} catch (Exception ex) {
@ -419,25 +395,24 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^Integer data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
try {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
int assertedValue = Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, settings));
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
int assertedValue = Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings()));
LOG.info("fieldName: " + fieldName + ", op: " + op + ", assertedValue: " + assertedValue);
//subsequent value comparisons are and-ed together while iterating over the list of items, so init to true
AtomicBoolean result = new AtomicBoolean(true);
AtomicReference<Integer> fieldValue = new AtomicReference<>();
//iterate through response data and ensure that with data, the statement fieldName "op" assertValue is true
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
fieldValue.set(Integer.parseInt(item.get(fieldName).toString()));
result.set(result.get() && TestUtils.compare(fieldValue.get(), op, assertedValue));
});
assertTrue(result.get());
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -446,11 +421,11 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^the response has results$", () -> {
try {
int count = from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).size();
int count = from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).size();
LOG.info("Results count is: " + count);
assertTrue("ERROR: no results returned from the server!", count > 0);
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -459,13 +434,13 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^the response has singleton results in \"([^\"]*)\"", (String parameterFieldName) -> {
try {
String value = Settings.resolveParametersString(parameterFieldName, settings);
boolean isPresent = from(container.get().responseData.get()).get() != null;
LOG.info("Response value is: " + value);
LOG.info("IsPresent: " + isPresent);
String value = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
boolean isPresent = from(getTestContainer().getResponseData()).get() != null;
assertTrue("ERROR: singleton results not found for '" + value + "'!", isPresent);
LOG.info("Response value is: " + value);
LOG.info("Is Present: " + isPresent);
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -474,12 +449,12 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^the number of results is less than or equal to \"([^\"]*)\"$", (String limitField) -> {
try {
int count = from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).size(),
limit = Integer.parseInt(Settings.resolveParametersString(limitField, settings));
int count = from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).size(),
limit = Integer.parseInt(Settings.resolveParametersString(limitField, getTestContainer().getSettings()));
LOG.info("Results count is: " + count + ", Limit is: " + limit);
assertTrue("ERROR: number of results exceeds that specified in '" + limitField + "'!", count <= limit);
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -488,9 +463,9 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^Integer data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String opLhs, String parameterAssertedLhsValue, String andOrOp, String opRhs, String parameterAssertedRhsValue) -> {
try {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
Integer assertedLhsValue = Integer.parseInt(Settings.resolveParametersString(parameterAssertedLhsValue, settings)),
assertedRhsValue = Integer.parseInt(Settings.resolveParametersString(parameterAssertedRhsValue, settings));
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
Integer assertedLhsValue = Integer.parseInt(Settings.resolveParametersString(parameterAssertedLhsValue, getTestContainer().getSettings())),
assertedRhsValue = Integer.parseInt(Settings.resolveParametersString(parameterAssertedRhsValue, getTestContainer().getSettings()));
String op = andOrOp.toLowerCase();
boolean isAndOp = op.contains(AND);
@ -504,7 +479,7 @@ public class WebAPIServer_1_0_2 implements En {
rhsValue = new AtomicReference<>();
//iterate through response data and ensure that with data, the statement fieldName "op" assertValue is true
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
lhsValue.set(Integer.parseInt(item.get(fieldName).toString()));
rhsValue.set(Integer.parseInt(item.get(fieldName).toString()));
@ -523,7 +498,7 @@ public class WebAPIServer_1_0_2 implements En {
}
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -532,14 +507,14 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^Date data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
try {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
AtomicReference<Date> fieldValue = new AtomicReference<>();
AtomicReference<Date> assertedValue = new AtomicReference<>();
assertedValue.set(TestUtils.parseDateFromEdmDateString(Settings.resolveParametersString(parameterAssertedValue, settings)));
assertedValue.set(TestUtils.parseDateFromEdmDateString(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings())));
LOG.info("Asserted value is: " + assertedValue.get().toString());
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
try {
fieldValue.set(TestUtils.parseDateFromEdmDateTimeOffsetString(item.get(fieldName).toString()));
assertTrue(TestUtils.compare(fieldValue.get(), op, assertedValue.get()));
@ -548,7 +523,7 @@ public class WebAPIServer_1_0_2 implements En {
}
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -557,23 +532,23 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^TimeOfDay data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
try {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
AtomicReference<Time> fieldValue = new AtomicReference<>();
AtomicReference<Time> assertedValue = new AtomicReference<>();
assertedValue.set(TestUtils.parseTimeOfDayFromEdmTimeOfDayString(Settings.resolveParametersString(parameterAssertedValue, settings)));
assertedValue.set(TestUtils.parseTimeOfDayFromEdmTimeOfDayString(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings())));
LOG.info("Asserted value is: " + assertedValue.get().toString());
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
try {
fieldValue.set(TestUtils.parseTimeOfDayFromEdmDateTimeOffsetString(item.get(fieldName).toString()));
assertTrue(TestUtils.compare(fieldValue.get(), op, assertedValue.get()));
} catch (Exception ex) {
LOG.error(ex.getMessage());
LOG.error(ex.toString());
}
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -582,9 +557,9 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^DateTimeOffset data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
try {
TestUtils.assertDateTimeOffset(parameterFieldName, op, parameterAssertedValue, container.get().responseData.get(), settings);
TestUtils.assertDateTimeOffset(parameterFieldName, op, parameterAssertedValue, getTestContainer().getResponseData(), getTestContainer().getSettings());
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -593,9 +568,9 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^DateTimeOffset data in \"([^\"]*)\" \"([^\"]*)\" now\\(\\)$", (String parameterFieldName, String op) -> {
try {
TestUtils.assertDateTimeOffset(parameterFieldName, op, Timestamp.from(Instant.now()), container.get().responseData.get(), settings);
TestUtils.assertDateTimeOffset(parameterFieldName, op, Timestamp.from(Instant.now()), getTestContainer().getResponseData(), getTestContainer().getSettings());
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -604,23 +579,23 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^Single Valued Enumeration Data in \"([^\"]*)\" has \"([^\"]*)\"$", (String parameterFieldName, String parameterAssertedValue) -> {
try {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
AtomicReference<String> fieldValue = new AtomicReference<>();
AtomicReference<String> assertedValue = new AtomicReference<>();
AtomicBoolean result = new AtomicBoolean(false);
assertedValue.set(Settings.resolveParametersString(parameterAssertedValue, settings));
assertedValue.set(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings()));
LOG.info("Asserted value is: " + assertedValue.get());
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
fieldValue.set(item.get(fieldName).toString());
result.set(fieldValue.get().contentEquals(assertedValue.get()));
LOG.info("Assert True: " + fieldValue.get() + " equals " + assertedValue.get() + " ==> " + result.get());
assertTrue(result.get());
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -630,23 +605,23 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^Multiple Valued Enumeration Data in \"([^\"]*)\" has \"([^\"]*)\"$", (String parameterFieldName, String parameterAssertedValue) -> {
try {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
AtomicReference<String> fieldValue = new AtomicReference<>();
AtomicReference<String> assertedValue = new AtomicReference<>();
AtomicBoolean result = new AtomicBoolean(false);
assertedValue.set(Settings.resolveParametersString(parameterAssertedValue, settings));
assertedValue.set(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings()));
LOG.info("Asserted value is: " + assertedValue.get());
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, ObjectNode.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, ObjectNode.class).forEach(item -> {
fieldValue.set(item.get(fieldName).toString());
result.set(fieldValue.get().contains(assertedValue.get()));
LOG.info("Assert True: " + fieldValue.get() + " has " + assertedValue.get() + " ==> " + result.get());
assertTrue(result.get());
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -655,7 +630,7 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^DateTimeOffset data in \"([^\"]*)\" is sorted in \"([^\"]*)\" order$", (String parameterFieldName, String parameterOrderByDirection) -> {
try {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
final String ASC = "asc", DESC = "desc";
AtomicReference<String> orderBy = new AtomicReference<>(parameterOrderByDirection.toLowerCase());
@ -666,7 +641,7 @@ public class WebAPIServer_1_0_2 implements En {
AtomicReference<Timestamp> currentValue = new AtomicReference<>();
AtomicInteger count = new AtomicInteger(0);
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
try {
if (count.get() == 0) {
initialValue.set(TestUtils.parseTimestampFromEdmDateTimeOffsetString(item.get(fieldName).toString()));
@ -681,11 +656,11 @@ public class WebAPIServer_1_0_2 implements En {
}
count.getAndIncrement();
} catch (EdmPrimitiveTypeException ptex) {
fail(ptex.getMessage());
fail(ptex.toString());
}
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -693,26 +668,26 @@ public class WebAPIServer_1_0_2 implements En {
* Date Field comparisons
*/
And("^\"([^\"]*)\" data in Date Field \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String stringDatePart, String parameterFieldName, String op, String parameterAssertedValue) -> {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
AtomicReference<Integer> fieldValue = new AtomicReference<>();
AtomicInteger assertedValue = new AtomicInteger();
AtomicReference<String> datePart = new AtomicReference<>(stringDatePart.toLowerCase());
AtomicReference<String> operator = new AtomicReference<>(op.toLowerCase());
try {
assertedValue.set(Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, settings)));
assertedValue.set(Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings())));
LOG.info("Asserted value is: " + assertedValue.get());
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
try {
fieldValue.set(TestUtils.getDatePart(datePart.get(), item.get(fieldName)));
assertTrue(TestUtils.compare(fieldValue.get(), operator.get(), assertedValue.get()));
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -722,29 +697,29 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^\"([^\"]*)\" data in Timestamp Field \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String stringDatePart, String parameterFieldName, String op, String parameterAssertedValue) -> {
try {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
AtomicReference<Integer> fieldValue = new AtomicReference<>();
AtomicReference<Integer> assertedValue = new AtomicReference<>();
AtomicReference<String> datePart = new AtomicReference<>(stringDatePart.toLowerCase());
AtomicReference<String> operator = new AtomicReference<>(op.toLowerCase());
try {
assertedValue.set(Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, settings)));
assertedValue.set(Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings())));
LOG.info("Asserted value is: " + assertedValue.get().toString());
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
try {
fieldValue.set(TestUtils.getTimestampPart(datePart.get(), item.get(fieldName).toString()));
assertTrue(TestUtils.compare(fieldValue.get(), operator.get(), assertedValue.get()));
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -753,15 +728,15 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^String data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
try {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
AtomicReference<String> assertedValue = new AtomicReference<>(Settings.resolveParametersString(parameterAssertedValue, settings));
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
AtomicReference<String> assertedValue = new AtomicReference<>(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings()));
AtomicReference<String> operator = new AtomicReference<>(op.toLowerCase());
from(container.get().responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
assertTrue(TestUtils.compare(item.get(fieldName).toString(), operator.get(), assertedValue.get()));
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -774,11 +749,11 @@ public class WebAPIServer_1_0_2 implements En {
Checks that metadata are accessible and contain the resource name specified in generic.resoscript
*/
And("^the metadata contains the \"([^\"]*)\" resource$", (String parameterResourceName) -> {
final String resourceName = Settings.resolveParametersString(parameterResourceName, settings);
final String resourceName = Settings.resolveParametersString(parameterResourceName, getTestContainer().getSettings());
AtomicReference<CsdlEntityContainer> entityContainer = new AtomicReference<>();
try {
entityContainer.set(TestUtils.findDefaultEntityContainer(edm.get(), xmlMetadata.get()));
entityContainer.set(TestUtils.findDefaultEntityContainer(getTestContainer().getEdm(), getTestContainer().getXMLMetadata()));
assertNotNull("ERROR: server metadata does not contain the given resource name: " + resourceName,
entityContainer.get().getEntitySet(resourceName));
@ -786,7 +761,7 @@ public class WebAPIServer_1_0_2 implements En {
LOG.info("Found EntityContainer for the given resource: '" + resourceName + "'");
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -795,15 +770,15 @@ public class WebAPIServer_1_0_2 implements En {
* all of the fields in the given parameterSelectList.
*/
And("^resource metadata for \"([^\"]*)\" contains the fields in \"([^\"]*)\"$", (String parameterResourceName, String parameterSelectList) -> {
final String selectList = Settings.resolveParametersString(parameterSelectList, settings);
final String selectList = Settings.resolveParametersString(parameterSelectList, getTestContainer().getSettings());
try {
final String resourceName = Settings.resolveParametersString(parameterResourceName, settings);
final String resourceName = Settings.resolveParametersString(parameterResourceName, getTestContainer().getSettings());
List<String> fieldNames = Arrays.asList(selectList.split(FIELD_SEPARATOR));
//create field lookup
Map<String, CsdlProperty> fieldMap = new HashMap<>();
TestUtils.findEntityTypesForEntityTypeName(edm.get(), xmlMetadata.get(), resourceName)
TestUtils.findEntityTypesForEntityTypeName(getTestContainer().getEdm(), getTestContainer().getXMLMetadata(), resourceName)
.forEach(csdlProperty -> fieldMap.put(csdlProperty.getName(), csdlProperty));
LOG.info("Searching metadata for fields in given select list: " + selectList);
@ -813,7 +788,7 @@ public class WebAPIServer_1_0_2 implements En {
LOG.info("Found: '" + fieldName.trim() + "'");
});
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -821,22 +796,16 @@ public class WebAPIServer_1_0_2 implements En {
* Finds default Edm entity container at the given Service Root.
* Note that this assumes the server can process the Accept application/xml header!
*/
When("^a default entity container exists for the service root in \"([^\"]*)\"$", (String clientSettingsServiceRoot) -> {
final String serviceRoot = Settings.resolveParametersString(clientSettingsServiceRoot, settings);
assertEquals("ERROR: given service root doesn't match the one configured in the Commander", serviceRoot, container.get().commander.get().getServiceRoot());
When("^the metadata contains a valid service document$", () -> {
try {
ODataRetrieveResponse<Edm> oDataRetrieveResponse = container.get().commander.get().getODataRetrieveEdmResponse();
container.get().responseCode.set(oDataRetrieveResponse.getStatusCode());
edm.set(oDataRetrieveResponse.getBody());
assertNotNull("ERROR: could not find default entity container for given service root: " + serviceRoot, edm.get().getEntityContainer());
LOG.info("Found Default Entity Container: '" + edm.get().getEntityContainer().getNamespace() + "'");
assertNotNull("ERROR: could not find default entity container for given service root: " +
getTestContainer().getServiceRoot(), getTestContainer().getEdm().getEntityContainer());
LOG.info("Found Default Entity Container: '" + getTestContainer().getEdm().getEntityContainer().getNamespace() + "'");
} catch (ODataClientErrorException cex) {
container.get().responseCode.set(cex.getStatusLine().getStatusCode());
fail(cex.getMessage());
getTestContainer().setResponseCode(cex.getStatusLine().getStatusCode());
fail(cex.toString());
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
@ -844,18 +813,33 @@ public class WebAPIServer_1_0_2 implements En {
* XML Metadata getter
*/
And("^XML Metadata are requested from the service root in \"([^\"]*)\"$", (String clientSettingsServiceRoot) -> {
final String serviceRoot = Settings.resolveParametersString(clientSettingsServiceRoot, settings);
assertEquals("ERROR: given service root doesn't match the one configured in the Commander", serviceRoot, container.get().commander.get().getServiceRoot());
final String serviceRoot = Settings.resolveParametersString(clientSettingsServiceRoot, getTestContainer().getSettings());
assertEquals("ERROR: given service root doesn't match the one configured in the Commander", serviceRoot, getTestContainer().getCommander().getServiceRoot());
try {
xmlMetadata.set(container.get().commander.get().getXMLMetadata());
assertNotNull("ERROR: could not find valid XML Metadata for given service root: " + serviceRoot, xmlMetadata.get());
LOG.info("XML Metadata retrieved from: " + serviceRoot);
assertNotNull("ERROR: could not find valid XML Metadata for given service root: " + serviceRoot, getTestContainer().getXMLMetadata());
} catch (ODataClientErrorException cex) {
container.get().responseCode.set(cex.getStatusLine().getStatusCode());
fail(cex.getMessage());
getTestContainer().setResponseCode(cex.getStatusLine().getStatusCode());
fail(cex.toString());
} catch (Exception ex) {
fail(ex.getMessage());
fail(ex.toString());
}
});
/*
* Edm Metadata getter
*/
And("^Edm metadata are requested from the service root in \"([^\"]*)\"$", (String clientSettingsServiceRoot) -> {
final String serviceRoot = Settings.resolveParametersString(clientSettingsServiceRoot, getTestContainer().getSettings());
assertEquals("ERROR: given service root doesn't match the one configured in the Commander", serviceRoot, getTestContainer().getCommander().getServiceRoot());
try {
assertNotNull("ERROR: could not find valid Edm Metadata for given service root: " + serviceRoot, getTestContainer().getEdm());
} catch (ODataClientErrorException cex) {
getTestContainer().setResponseCode(cex.getStatusLine().getStatusCode());
fail(cex.toString());
} catch (Exception ex) {
fail(ex.toString());
}
});
@ -863,10 +847,10 @@ public class WebAPIServer_1_0_2 implements En {
* Tests whether a navigation property can be found in the given resource name.
*/
And("^an OData NavigationProperty exists for the given \"([^\"]*)\"$", (String parameterEndpointResource) -> {
String resourceName = Settings.resolveParametersString(parameterEndpointResource, settings);
String resourceName = Settings.resolveParametersString(parameterEndpointResource, getTestContainer().getSettings());
List<CsdlNavigationProperty> navigationProperties
= TestUtils.findNavigationPropertiesForEntityTypeName(container.get().commander.get().getEdm(), container.get().commander.get().getXMLMetadata(), resourceName);
= TestUtils.findNavigationPropertiesForEntityTypeName(getTestContainer().getEdm(), getTestContainer().getXMLMetadata(), resourceName);
assertTrue("ERROR: no navigation properties found for the given '" + resourceName + "' resource!",
navigationProperties.size() > 0);
@ -883,10 +867,10 @@ public class WebAPIServer_1_0_2 implements En {
* Checks to see whether the expanded field has data
*/
And("^data are present within the expanded field \"([^\"]*)\"$", (String parameterExpandField) -> {
String expandField = Settings.resolveParametersString(parameterExpandField, settings);
String expandField = Settings.resolveParametersString(parameterExpandField, getTestContainer().getSettings());
assertFalse("ERROR: no expand field found for " + parameterExpandField, expandField.isEmpty());
ClientEntitySet results = container.get().commander.get().getClient().getRetrieveRequestFactory().getEntitySetRequest(container.get().requestUri.get()).execute().getBody();
ClientEntitySet results = getTestContainer().getCommander().getClient().getRetrieveRequestFactory().getEntitySetRequest(getTestContainer().getRequestUri()).execute().getBody();
LOG.info("Results count is: " + results.getEntities().size());
AtomicInteger counter = new AtomicInteger();
@ -920,14 +904,15 @@ public class WebAPIServer_1_0_2 implements En {
* Checks the Standard Resources requirement from Section 2.6 of the Web API specification
*/
And("^the metadata contains at least one resource from \"([^\"]*)\"$", (String parameterRequiredResourceList) -> {
String requiredResourceString = Settings.resolveParametersString(parameterRequiredResourceList, settings).replace(" ", "");
String requiredResourceString = Settings.resolveParametersString(parameterRequiredResourceList, getTestContainer().getSettings()).replace(" ", "");
List<String> requiredResources = Arrays.asList(requiredResourceString.split(","));
LOG.info("Searching the default entity container for one of the following Standard Resources: " + requiredResourceString.replace(FIELD_SEPARATOR, PRETTY_FIELD_SEPARATOR));
AtomicBoolean found = new AtomicBoolean(false);
requiredResources.forEach(requiredResource -> {
if (!found.get()) found.set(found.get() || edm.get().getEntityContainer().getEntitySet(requiredResource) != null);
if (!found.get())
found.set(found.get() || getTestContainer().getEdm().getEntityContainer().getEntitySet(requiredResource) != null);
});
assertTrue("ERROR: could not find one of the following Standard Resource Names in the default entity container: " + requiredResourceString.replace(FIELD_SEPARATOR, PRETTY_FIELD_SEPARATOR),
@ -941,8 +926,8 @@ public class WebAPIServer_1_0_2 implements En {
* latest version of the Data Dictionary, currently 1.7.
*/
And("^the given \"([^\"]*)\" resource exists within \"([^\"]*)\"$", (String parameterResourceName, String parameterResourceList) -> {
String resourceName = Settings.resolveParametersString(parameterResourceName, settings),
allowedResourceString = Settings.resolveParametersString(parameterResourceList, settings).replace(" ", "");
String resourceName = Settings.resolveParametersString(parameterResourceName, getTestContainer().getSettings()),
allowedResourceString = Settings.resolveParametersString(parameterResourceList, getTestContainer().getSettings()).replace(" ", "");
List<String> allowedResources = new ArrayList<>(Arrays.asList(allowedResourceString.split(FIELD_SEPARATOR)));
LOG.info("Resource Name: " + resourceName);
@ -954,23 +939,23 @@ public class WebAPIServer_1_0_2 implements En {
When("^a GET request is made to the resolved Url in \"([^\"]*)\" using the OData Client$", (String parameterRequestId) -> {
String uriString = Settings.resolveParameters(settings.getRequestById(parameterRequestId), settings).getUrl();
String uriString = Settings.resolveParameters(getTestContainer().getSettings().getRequestById(parameterRequestId), getTestContainer().getSettings()).getUrl();
assertTrue("ERROR: the resolved Url in '" + parameterRequestId + "' was invalid!", uriString != null && uriString.length() > 0);
LOG.info("Request Id: " + parameterRequestId);
try {
container.get().requestUri.set(prepareUri(uriString));
container.get().clientEntitySetRequest.set(container.get().commander.get().getClient().getRetrieveRequestFactory().getEntitySetRequest(container.get().requestUri.get()));
getTestContainer().setRequestUri(prepareUri(uriString));
getTestContainer().setClientEntitySetRequest(getTestContainer().getCommander().getClient().getRetrieveRequestFactory().getEntitySetRequest(getTestContainer().getRequestUri()));
LOG.info("OData Client Request being made to: " + uriString);
container.get().clientEntitySetResponse.set(container.get().clientEntitySetRequest.get().execute());
getTestContainer().setClientEntitySetRequest(getTestContainer().getClientEntitySetRequest());
getTestContainer().setClientEntitySetResponse(getTestContainer().getClientEntitySetRequest().execute());
getTestContainer().setResponseCode(getTestContainer().getClientEntitySetResponse().getStatusCode());
container.get().responseCode.set(container.get().clientEntitySetResponse.get().getStatusCode());
ResWrap<EntityCollection> coll = (container.get().commander.get().getClient().getDeserializer(ContentType.JSON).toEntitySet(container.get().clientEntitySetResponse.get().getRawResponse()));
container.get().clientEntitySet.set(container.get().commander.get().getClient().getBinder().getODataEntitySet(coll));
ResWrap<EntityCollection> coll = (getTestContainer().getCommander().getClient().getDeserializer(ContentType.JSON).toEntitySet(getTestContainer().getClientEntitySetResponse().getRawResponse()));
getTestContainer().setClientEntitySet(getTestContainer().getCommander().getClient().getBinder().getODataEntitySet(coll));
} catch (ODataClientErrorException cex) {
container.get().oDataClientErrorException.set(cex);
container.get().responseCode.set(cex.getStatusLine().getStatusCode());
getTestContainer().setODataClientErrorException(cex);
getTestContainer().setResponseCode(cex.getStatusLine().getStatusCode());
} catch (Exception ex) {
fail(ex.toString());
}
@ -980,28 +965,32 @@ public class WebAPIServer_1_0_2 implements En {
* Uses the OData ClientEntitySet rather than raw JSON responses for comparisons
*/
And("^client entity set Integer data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String operator, String parameterFieldValue) -> {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings),
op = operator.trim().toLowerCase();
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings()),
op = operator.trim().toLowerCase();
Integer fieldValue = Integer.parseInt(Settings.resolveParametersString(parameterFieldValue, settings));
Integer fieldValue = Integer.parseInt(Settings.resolveParametersString(parameterFieldValue, getTestContainer().getSettings()));
assertNotNull(fieldValue);
container.get().clientEntitySet.get().getEntities().forEach(entity -> {
assertTrue(compare((Integer)entity.getProperty(fieldName).getValue().asPrimitive().toValue(), op, fieldValue));
getTestContainer().getClientEntitySet().getEntities().forEach(entity -> {
assertTrue(compare((Integer) entity.getProperty(fieldName).getValue().asPrimitive().toValue(), op, fieldValue));
});
});
And("^the OData client response has client entity set data$", () -> {
assertNotNull("ERROR: no entity collection returned in response!", container.get().clientEntitySet.get());
assertTrue("ERROR: no results returned!", container.get().clientEntitySet.get().getCount() > 0);
assertNotNull("ERROR: no entity collection returned in response!", getTestContainer().getClientEntitySet());
assertTrue("ERROR: no results returned!", getTestContainer().getClientEntitySet().getCount() > 0);
if (showResponses) {
container.get().clientEntitySet.get().getEntities().forEach(entity -> {
getTestContainer().getClientEntitySet().getEntities().forEach(entity -> {
LOG.info("Entity Type is: " + entity.getTypeName());
entity.getProperties().forEach(property -> LOG.info("\tProperty: " + property.toString()));
});
}
});
}
static WebApiTestContainer getTestContainer() {
return container.get();
}
}

View File

@ -42,10 +42,6 @@ public class App {
private static final Logger LOG = LogManager.getLogger(App.class);
private static final String DIVIDER = "==============================================================";
private static final String SMALL_DIVIDER = "===========================";
private static final String RESOSCRIPT_EXTENSION = ".resoscript";
private static final String EDMX_EXTENSION = ".xml";
private static final String OUTPUT_DIR = "user.dir";
public static void main(String[] params) {
@ -132,18 +128,18 @@ public class App {
if (cmd.hasOption(APP_OPTIONS.ACTIONS.RUN_RESOSCRIPT)) {
int numRequests = settings.getRequests().size();
LOG.info(DIVIDER);
LOG.info(REPORT_DIVIDER);
LOG.info("Web API Commander Starting... Press <ctrl+c> at any time to exit.");
LOG.info(DIVIDER);
LOG.info(REPORT_DIVIDER);
LOG.info("Running " + numRequests + " Request(s)");
LOG.info("RESOScript: " + inputFilename);
LOG.info(DIVIDER + "\n\n");
LOG.info(REPORT_DIVIDER + "\n\n");
//put in local directory rather than relative to where the input file is
String directoryName = System.getProperty(OUTPUT_DIR),
outputPath = inputFilename
.substring(inputFilename.contains(File.separator) ? inputFilename.lastIndexOf(File.separator) : 0, inputFilename.length())
.substring(inputFilename.contains(File.separator) ? inputFilename.lastIndexOf(File.separator) : 0)
.replace(RESOSCRIPT_EXTENSION, "") + "-" + getTimestamp(new Date());
String resolvedUrl = null;
@ -160,9 +156,9 @@ public class App {
request = settings.getRequestsAsList().get(i);
//TODO: create dynamic JUnit (or similar) test runner
LOG.info(SMALL_DIVIDER);
LOG.info(REPORT_DIVIDER_SMALL);
LOG.info("Request: #" + (i + 1));
LOG.info(SMALL_DIVIDER);
LOG.info(REPORT_DIVIDER_SMALL);
if (request.getRequestId() != null && request.getRequestId().length() > 0) {
LOG.info("Request Id: " + request.getRequestId());
@ -193,9 +189,9 @@ public class App {
LOG.info("\n ");
}
LOG.info(DIVIDER);
LOG.info(REPORT_DIVIDER);
LOG.info("RESOScript Complete!");
LOG.info(DIVIDER + "\n");
LOG.info(REPORT_DIVIDER + "\n");
System.exit(OK); //terminate the program after the batch completes
}
@ -206,7 +202,7 @@ public class App {
if (cmd.hasOption(APP_OPTIONS.ACTIONS.GET_METADATA)) {
APP_OPTIONS.validateAction(cmd, APP_OPTIONS.ACTIONS.GET_METADATA);
metadata = commander.getEdm();
metadata = commander.prepareEdmMetadataRequest().execute().getBody();
getMetadataReport(metadata);
} else if (cmd.hasOption(APP_OPTIONS.ACTIONS.VALIDATE_METADATA)) {
@ -308,11 +304,12 @@ public class App {
/**
* Generates totals report from aggregates.
*
* @param totalRequestCount total request count
* @param numSucceeded num requests succeeded
* @param numFailed num requests failed
* @param numSkipped num requests skipped
* @param numIncomplete num requests incomplete
* @param numSucceeded num requests succeeded
* @param numFailed num requests failed
* @param numSkipped num requests skipped
* @param numIncomplete num requests incomplete
* @return a string containing the report.
*/
private static String generateTotalsReport(int totalRequestCount, int numSucceeded, int numFailed, int numSkipped, int numIncomplete) {
@ -326,48 +323,14 @@ public class App {
}
/**
* Metadata Pretty Printer
* Gets a formatted date string for the given date.
*
* @param metadata any metadata in Edm format
* @param date the date to format
* @return date string in yyyyMMddHHMMssS format
*/
private static String getMetadataReport(Edm metadata) {
StringBuilder reportBuilder = new StringBuilder();
reportBuilder.append("\n\n" + DIVIDER);
reportBuilder.append("\nMetadata Report");
reportBuilder.append("\n" + DIVIDER);
//Note: other treatments may be added to this summary info
metadata.getSchemas().forEach(schema -> {
reportBuilder.append("\n\nNamespace: ").append(schema.getNamespace());
reportBuilder.append("\n" + SMALL_DIVIDER);
schema.getTypeDefinitions().forEach(a ->
reportBuilder.append("\n\n\tType Definition:").append(a.getName()));
schema.getEntityTypes().forEach(a -> {
reportBuilder.append("\n\n\tEntity Type: ").append(a.getName());
a.getKeyPropertyRefs().forEach(ref ->
reportBuilder.append("\n\t\tKey Field: ").append(ref.getName()));
a.getPropertyNames().forEach(n -> reportBuilder.append("\n\t\tName: ").append(n));
});
schema.getEnumTypes().forEach(a -> {
reportBuilder.append("\n\n\tEnum Type: ").append(a.getName());
a.getMemberNames().forEach(n -> reportBuilder.append("\n\t\tName: ").append(n));
});
schema.getComplexTypes().forEach(a ->
reportBuilder.append("\n\n\tComplex Entity Type: ").append(a.getFullQualifiedName().getFullQualifiedNameAsString()));
schema.getAnnotationGroups().forEach(a ->
reportBuilder.append("\n\n\tAnnotation: ").append(a.getQualifier()).append(", Target Path: ").append(a.getTargetPath()));
schema.getTerms().forEach(a ->
reportBuilder.append("\n\n\tTerm: ").append(a.getFullQualifiedName().getFullQualifiedNameAsString()));
});
return reportBuilder.toString();
private static String getTimestamp(Date date) {
DateFormat df = new SimpleDateFormat("yyyyMMddHHMMssS");
return df.format(date);
}
/**
@ -388,16 +351,6 @@ public class App {
static String CONTENT_TYPE = "contentType";
static String HELP = "help";
static class ACTIONS {
//actions
static String RUN_RESOSCRIPT = "runRESOScript";
static String GET_METADATA = "getMetadata";
static String VALIDATE_METADATA = "validateMetadata";
static String GET_ENTITIES = "getEntities";
static String SAVE_RAW_GET_REQUEST = "saveRawGetRequest";
static String CONVERT_EDMX_TO_OPEN_API = "convertEDMXtoOpenAPI";
}
/**
* Validates options for the various actions exposed in App.
* <p>
@ -530,28 +483,28 @@ public class App {
.desc("Converts EDMX in <inputFile> to Open API, saving it in <inputFile>.swagger.json").build());
return new Options()
.addOption(helpOption)
.addOption(hostNameOption)
.addOption(bearerTokenOption)
.addOption(inputFileOption)
.addOption(outputFileOption)
.addOption(pageLimit)
.addOption(pageSize)
.addOption(entityName)
.addOption(useEdmEnabledClient)
.addOption(uriOption)
.addOption(contentType)
.addOptionGroup(actions);
.addOption(helpOption)
.addOption(hostNameOption)
.addOption(bearerTokenOption)
.addOption(inputFileOption)
.addOption(outputFileOption)
.addOption(pageLimit)
.addOption(pageSize)
.addOption(entityName)
.addOption(useEdmEnabledClient)
.addOption(uriOption)
.addOption(contentType)
.addOptionGroup(actions);
}
static class ACTIONS {
//actions
static String RUN_RESOSCRIPT = "runRESOScript";
static String GET_METADATA = "getMetadata";
static String VALIDATE_METADATA = "validateMetadata";
static String GET_ENTITIES = "getEntities";
static String SAVE_RAW_GET_REQUEST = "saveRawGetRequest";
static String CONVERT_EDMX_TO_OPEN_API = "convertEDMXtoOpenAPI";
}
}
/**
* Gets a formatted date string for the given date.
* @param date the date to format
* @return date string in yyyyMMddHHMMssS format
*/
private static String getTimestamp(Date date) {
DateFormat df = new SimpleDateFormat("yyyyMMddHHMMssS");
return df.format(date);
}
}

View File

@ -1,6 +1,7 @@
package org.reso.commander;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.apache.http.client.utils.URIBuilder;
import org.apache.logging.log4j.LogManager;
@ -8,10 +9,12 @@ import org.apache.logging.log4j.Logger;
import org.apache.olingo.client.api.ODataClient;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest;
import org.apache.olingo.client.api.communication.request.retrieve.XMLMetadataRequest;
import org.apache.olingo.client.api.communication.response.ODataRawResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.domain.ClientEntitySet;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.client.api.serialization.ODataSerializerException;
import org.apache.olingo.client.core.ODataClientFactory;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.format.ContentType;
@ -45,7 +48,13 @@ public class Commander {
public static final int NOT_OK = 1;
public static final Integer DEFAULT_PAGE_SIZE = 10;
public static final Integer DEFAULT_PAGE_LIMIT = 1;
public static final String REPORT_DIVIDER = "==============================================================";
public static final String REPORT_DIVIDER_SMALL = "===========================";
public static final String RESOSCRIPT_EXTENSION = ".resoscript";
public static final String EDMX_EXTENSION = ".xml";
private static final Logger LOG = LogManager.getLogger(Commander.class);
private static final String EDM_4_0_3_XSD = "edm.4.0.3.xsd",
EDMX_4_0_3_XSD = "edmx.4.0.3.xsd";
private static String bearerToken;
private static String clientId;
private static String clientSecret;
@ -54,20 +63,21 @@ public class Commander {
private static String redirectUri;
private static String scope;
private static boolean isTokenClient, isOAuthClient;
//one instance of client per Commander. See Builder
private static ODataClient client;
private static boolean useEdmEnabledClient;
private static String serviceRoot;
private static Edm edm;
private static XMLMetadata xmlMetadata;
//private constructor for internal use, use Builder to construct instances
private Commander() {
; //private constructor, should not be used. Use Builder instead.
//private constructor, should not be used. Use Builder instead.
}
/**
* Uses an XML validator to validate that the given string contains valid XML.
*
* @param xmlString the string containing the XML to validate.
* @return true if the given xmlString is valid and false otherwise.
*/
@ -75,8 +85,20 @@ public class Commander {
return validateXML(new ByteArrayInputStream(xmlString.getBytes()));
}
/**
* Validates XML for the given xmlMetadata item
*
* @param xmlMetadata the XML metadata to validate
* @return true if valid, false otherwise
* @throws ODataSerializerException if the given XML metadata could not be serialized
*/
public static boolean validateXML(XMLMetadata xmlMetadata) throws ODataSerializerException {
return validateXML(serializeXMLMetadataToXMLString(xmlMetadata));
}
/**
* Uses an XML validator to validate that the given inputStream contains valid XML.
*
* @param inputStream the input stream to check.
* @return true if the given inputStream has valid XML, false otherwise.
*/
@ -87,8 +109,8 @@ public class Commander {
factory.setNamespaceAware(true);
factory.setSchema(SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(new StreamSource[]{
new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("edm.4.0.3.xsd")),
new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("edmx.4.0.3.xsd"))
new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream(EDM_4_0_3_XSD)),
new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream(EDMX_4_0_3_XSD))
}));
SAXParser parser = factory.newSAXParser();
@ -110,6 +132,7 @@ public class Commander {
/**
* Prepares a URI for an OData request
*
* @param uriString the uri string to use for the request
* @return the prepared URI
*/
@ -145,24 +168,18 @@ public class Commander {
JSON_FULL_METADATA = "JSON_FULL_METADATA",
XML = "XML";
ContentType defaultType = ContentType.JSON;
ContentType type;
ContentType type = ContentType.JSON;
if (contentType == null) {
return defaultType;
} else {
if (contentType.matches(JSON)) {
type = ContentType.JSON;
} else if (contentType.matches(JSON_NO_METADATA)) {
type = ContentType.JSON_NO_METADATA;
} else if (contentType.matches(JSON_FULL_METADATA)) {
type = ContentType.JSON_FULL_METADATA;
} else if (contentType.matches(XML)) {
type = ContentType.APPLICATION_XML;
} else {
type = ContentType.JSON;
}
if (contentType.matches(JSON)) {
type = ContentType.JSON;
} else if (contentType.matches(JSON_NO_METADATA)) {
type = ContentType.JSON_NO_METADATA;
} else if (contentType.matches(JSON_FULL_METADATA)) {
type = ContentType.JSON_FULL_METADATA;
} else if (contentType.matches(XML)) {
type = ContentType.APPLICATION_XML;
}
return type;
}
@ -196,12 +213,70 @@ public class Commander {
return null;
}
/**
* Serializes XML Metadata to an XML string
*
* @param xmlMetadata the metadata to serialize
* @return a String containing the metadata
* @throws ODataSerializerException
*/
private static String serializeXMLMetadataToXMLString(XMLMetadata xmlMetadata) throws ODataSerializerException {
StringWriter writer = new StringWriter();
client.getSerializer(ContentType.APPLICATION_XML).write(writer, xmlMetadata);
return writer.getBuffer().toString();
}
/**
* Metadata Pretty Printer
*
* @param metadata any metadata in Edm format
*/
public static String getMetadataReport(Edm metadata) {
StringBuilder reportBuilder = new StringBuilder();
reportBuilder.append("\n\n" + REPORT_DIVIDER);
reportBuilder.append("\nMetadata Report");
reportBuilder.append("\n" + REPORT_DIVIDER);
//Note: other treatments may be added to this summary info
metadata.getSchemas().forEach(schema -> {
reportBuilder.append("\n\nNamespace: ").append(schema.getNamespace());
reportBuilder.append("\n" + REPORT_DIVIDER_SMALL);
schema.getTypeDefinitions().forEach(a ->
reportBuilder.append("\n\n\tType Definition:").append(a.getName()));
schema.getEntityTypes().forEach(a -> {
reportBuilder.append("\n\n\tEntity Type: ").append(a.getName());
a.getKeyPropertyRefs().forEach(ref ->
reportBuilder.append("\n\t\tKey Field: ").append(ref.getName()));
a.getPropertyNames().forEach(n -> reportBuilder.append("\n\t\tName: ").append(n));
});
schema.getEnumTypes().forEach(a -> {
reportBuilder.append("\n\n\tEnum Type: ").append(a.getName());
a.getMemberNames().forEach(n -> reportBuilder.append("\n\t\tName: ").append(n));
});
schema.getComplexTypes().forEach(a ->
reportBuilder.append("\n\n\tComplex Entity Type: ").append(a.getFullQualifiedName().getFullQualifiedNameAsString()));
schema.getAnnotationGroups().forEach(a ->
reportBuilder.append("\n\n\tAnnotation: ").append(a.getQualifier()).append(", Target Path: ").append(a.getTargetPath()));
schema.getTerms().forEach(a ->
reportBuilder.append("\n\n\tTerm: ").append(a.getFullQualifiedName().getFullQualifiedNameAsString()));
});
return reportBuilder.toString();
}
public ODataClient getClient() {
return this.client;
return client;
}
public void setClient(ODataClient client) {
this.client = client;
Commander.client = client;
}
public String getTokenUri() {
@ -231,42 +306,22 @@ public class Commander {
}
/**
* Gets server metadata in Edm format.
*
* @return
* @implNote the data in this item are cached in the commander once fetched
*/
public Edm getEdm() {
if (edm == null) {
edm = getODataRetrieveEdmResponse().getBody();
}
return edm;
}
/**
* Gets server metadata in XMLMetadata format.
*
* @return XMLMetadata representation of the server metadata.
* @implNote the data in this item are cached in the commander once fetched
*/
public XMLMetadata getXMLMetadata() {
if (xmlMetadata == null) {
EdmMetadataRequest metadataRequest = client.getRetrieveRequestFactory().getMetadataRequest(serviceRoot);
LOG.info("Fetching XMLMetadata with OData Client from: " + metadataRequest.getURI().toString());
xmlMetadata = metadataRequest.getXMLMetadata();
}
return xmlMetadata;
}
/**
* Used to contain the response for the request as well as get metadata.
* Prepares an Edm Metadata request
*
* @return the OData response retrieved from the server when making the request.
*/
public ODataRetrieveResponse<Edm> getODataRetrieveEdmResponse() {
EdmMetadataRequest metadataRequest = client.getRetrieveRequestFactory().getMetadataRequest(serviceRoot);
LOG.info("Fetching Edm with OData Client from: " + metadataRequest.getURI().toString());
return metadataRequest.execute();
public EdmMetadataRequest prepareEdmMetadataRequest() {
EdmMetadataRequest request = getClient().getRetrieveRequestFactory().getMetadataRequest(getServiceRoot());
request.addCustomHeader(HttpHeaders.CONTENT_TYPE, null);
request.addCustomHeader(HttpHeaders.ACCEPT, null);
return request;
}
public XMLMetadataRequest prepareXMLMetadataRequest() {
XMLMetadataRequest request = getClient().getRetrieveRequestFactory().getXMLMetadataRequest(getServiceRoot());
request.addCustomHeader(HttpHeaders.CONTENT_TYPE, null);
request.addCustomHeader(HttpHeaders.ACCEPT, null);
return request;
}
/**
@ -290,13 +345,9 @@ public class Commander {
* @param metadata the metadata to save.
* @param outputFileName the file name to output the metadata to.
*/
public void saveMetadata(Edm metadata, String outputFileName) {
try {
FileWriter writer = new FileWriter(outputFileName);
client.getSerializer(ContentType.APPLICATION_XML).write(writer, metadata);
} catch (Exception ex) {
LOG.error(ex.getStackTrace());
}
public void saveMetadata(Edm metadata, String outputFileName) throws IOException, ODataSerializerException {
FileWriter writer = new FileWriter(outputFileName);
client.getSerializer(ContentType.APPLICATION_XML).write(writer, metadata);
}
/**
@ -351,6 +402,7 @@ public class Commander {
/**
* Ensures that the input stream contains valid XMLMetadata.
*
* @param inputStream the input stream containing the metadata to validate.
* @return true if the given input stream contains valid XML Metadata, false otherwise.
*/
@ -384,6 +436,7 @@ public class Commander {
/**
* Boolean to determine whether this Commander instance is a token client.
*
* @return true if the commander instance is a token client, false otherwise.
*/
public boolean isTokenClient() {
@ -392,6 +445,7 @@ public class Commander {
/**
* Boolean to determine whether this Commander instance is an OAuth2 client.
*
* @return true if the commander instance is an OAuth2 client credentials client, false otherwise.
*/
public boolean isOAuthClient() {
@ -641,8 +695,8 @@ public class Commander {
//items required for OAuth client
isOAuthClient =
clientId != null && clientId.length() > 0
&& clientSecret != null && clientSecret.length() > 0
&& tokenUri != null && tokenUri.length() > 0;
&& clientSecret != null && clientSecret.length() > 0
&& tokenUri != null && tokenUri.length() > 0;
//items required for token client
isTokenClient = bearerToken != null && bearerToken.length() > 0;

View File

@ -2,16 +2,9 @@ package org.reso.commander;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.Header;
import org.apache.http.HttpStatus;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.ODataServerErrorException;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
import org.apache.olingo.client.api.communication.response.ODataRawResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.domain.ClientEntitySet;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
@ -22,7 +15,6 @@ import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
import org.apache.olingo.commons.core.edm.primitivetype.EdmDate;
import org.apache.olingo.commons.core.edm.primitivetype.EdmDateTimeOffset;
import org.apache.olingo.commons.core.edm.primitivetype.EdmTimeOfDay;
import org.reso.models.Request;
import org.reso.models.Settings;
import java.io.BufferedReader;
@ -41,58 +33,18 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import static io.restassured.path.json.JsonPath.from;
import static org.junit.Assert.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public final class TestUtils {
public static final String JSON_VALUE_PATH = "value";
public static final String HEADER_ODATA_VERSION = "OData-Version";
private static final Logger LOG = LogManager.getLogger(TestUtils.class);
/**
* Encapsulates Commander Requests and Responses during runtime
*/
public static final class TestContainer {
//TODO: Wrap in Commander Request/Response object
public AtomicReference<Commander> commander = new AtomicReference<>();
public AtomicReference<ODataRawResponse> oDataRawResponse = new AtomicReference<>();
public AtomicReference<Request> request = new AtomicReference<>();
public AtomicReference<URI> requestUri = new AtomicReference<>();
public AtomicReference<Integer> responseCode = new AtomicReference<>();
public AtomicReference<String> responseData = new AtomicReference<>();
public AtomicReference<String> initialResponseData = new AtomicReference<>(); //used if two result sets need to be compared
public AtomicReference<ODataRawRequest> rawRequest = new AtomicReference<>();
public AtomicReference<ODataClientErrorException> oDataClientErrorException = new AtomicReference<>();
public AtomicReference<ODataServerErrorException> oDataServerErrorException = new AtomicReference<>();
public AtomicReference<String> serverODataHeaderVersion = new AtomicReference<>();
public AtomicReference<Boolean> testAppliesToServerODataHeaderVersion = new AtomicReference<>();
public AtomicReference<ODataEntitySetRequest<ClientEntitySet>> clientEntitySetRequest = new AtomicReference<>();
public AtomicReference<ODataRetrieveResponse<ClientEntitySet>> clientEntitySetResponse = new AtomicReference<>();
public AtomicReference<ClientEntitySet> clientEntitySet = new AtomicReference<>();
/**
* Resets the state of the test container
*/
public void resetState() {
oDataRawResponse.set(null);
request.set(null);
responseCode.set(null);
responseData.set(null);
initialResponseData.set(null);
rawRequest.set(null);
oDataClientErrorException.set(null);
oDataServerErrorException.set(null);
serverODataHeaderVersion.set(null);
testAppliesToServerODataHeaderVersion.set(false);
}
}
/**
* Used to prepare URIs given that the input queryStrings can sometimes contain special characters
* that need to be ensured that they be processed.
*
* @param queryString the queryString to prepare
* @return the prepared URI with special characters in the queryString processed.
*/
@ -104,41 +56,6 @@ public final class TestUtils {
);
}
/**
* Executes HTTP GET request and sets the expected local variables in the given TestContainer
* Handles exceptions and sets response codes as well.
* @param uri the URI to make requests to
* @param container the TestContainer to execute the requests in
* @return a TestContainer containing the final state of the request.
*/
public static TestContainer executeGetRequest(final URI uri, TestContainer container) {
LOG.info("Request URI: " + uri);
try {
container.rawRequest.set(container.commander.get().getClient().getRetrieveRequestFactory().getRawRequest(uri));
container.oDataRawResponse.set(container.rawRequest.get().execute());
container.responseData.set(TestUtils.convertInputStreamToString(container.oDataRawResponse.get().getRawResponse()));
container.serverODataHeaderVersion.set(container.oDataRawResponse.get().getHeader(HEADER_ODATA_VERSION).toString());
container.responseCode.set(container.oDataRawResponse.get().getStatusCode());
LOG.info("Request succeeded..." + container.responseData.get().getBytes().length + " bytes received.");
} catch (ODataClientErrorException cex) {
LOG.debug("ODataClientErrorException caught. Check tests for asserted conditions...");
container.oDataClientErrorException.set(cex);
container.serverODataHeaderVersion.set(TestUtils.getHeaderData(HEADER_ODATA_VERSION, cex.getHeaderInfo()));
container.responseCode.set(cex.getStatusLine().getStatusCode());
} catch (ODataServerErrorException ode) {
LOG.debug("ODataServerErrorException thrown in executeGetRequest. Check tests for asserted conditions...");
//TODO: look for better ways to do this in Olingo or open PR
if (ode.getMessage().contains(Integer.toString(HttpStatus.SC_NOT_IMPLEMENTED))) {
container.responseCode.set(HttpStatus.SC_NOT_IMPLEMENTED);
}
container.oDataServerErrorException.set(ode);
} catch (Exception ex) {
fail("ERROR: unhandled Exception in executeGetRequest()!\n" + ex.toString());
//throw ex;
}
return container;
}
/**
* Finds the default entity container for the given configuration.
*

View File

@ -0,0 +1,15 @@
package org.reso.commander.certfication.containers;
public interface TestContainer {
/**
* Used to initialize the container from the given RESOScript
*/
void initialize();
/**
* Used to reset the state of the given TestContainer.
*/
void resetState();
}

View File

@ -0,0 +1,369 @@
package org.reso.commander.certfication.containers;
import org.apache.http.HttpStatus;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.ODataServerErrorException;
import org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
import org.apache.olingo.client.api.communication.response.ODataRawResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.domain.ClientEntitySet;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.commons.api.edm.Edm;
import org.reso.commander.Commander;
import org.reso.commander.TestUtils;
import org.reso.models.ClientSettings;
import org.reso.models.Request;
import org.reso.models.Settings;
import java.net.URI;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.fail;
import static org.reso.commander.TestUtils.HEADER_ODATA_VERSION;
/**
* Encapsulates Commander Requests and Responses during runtime
*/
public final class WebApiTestContainer implements TestContainer {
private static final Logger LOG = LogManager.getLogger(WebApiTestContainer.class);
private AtomicReference<Commander> commander = new AtomicReference<>();
private AtomicReference<ODataRawResponse> oDataRawResponse = new AtomicReference<>();
private AtomicReference<Request> request = new AtomicReference<>();
private AtomicReference<URI> requestUri = new AtomicReference<>();
private AtomicReference<Integer> responseCode = new AtomicReference<>();
private AtomicReference<String> responseData = new AtomicReference<>();
private AtomicReference<String> initialResponseData = new AtomicReference<>(); //used if two result sets need to be compared
private AtomicReference<ODataRawRequest> rawRequest = new AtomicReference<>();
private AtomicReference<ODataClientErrorException> oDataClientErrorException = new AtomicReference<>();
private AtomicReference<ODataServerErrorException> oDataServerErrorException = new AtomicReference<>();
private AtomicReference<String> serverODataHeaderVersion = new AtomicReference<>();
private AtomicReference<Boolean> testAppliesToServerODataHeaderVersion = new AtomicReference<>();
private AtomicReference<ODataEntitySetRequest<ClientEntitySet>> clientEntitySetRequest = new AtomicReference<>();
private AtomicReference<ODataRetrieveResponse<ClientEntitySet>> clientEntitySetResponse = new AtomicReference<>();
private AtomicReference<ClientEntitySet> clientEntitySet = new AtomicReference<>();
private AtomicReference<XMLMetadata> xmlMetadata = new AtomicReference<>();
private AtomicReference<Edm> edm = new AtomicReference<>();
private AtomicReference<Settings> settings = new AtomicReference<>();
private AtomicReference<String> serviceRoot = new AtomicReference<>();
private AtomicReference<String> bearerToken = new AtomicReference<>();
private AtomicReference<String> clientId = new AtomicReference<>();
private AtomicReference<String> clientSecret = new AtomicReference<>();
private AtomicReference<String> authorizationUri = new AtomicReference<>();
private AtomicReference<String> tokenUri = new AtomicReference<>();
private AtomicReference<String> redirectUri = new AtomicReference<>();
private AtomicReference<String> scope = new AtomicReference<>();
private AtomicReference<String> pathToRESOScript = new AtomicReference<>();
public void initialize() {
setServiceRoot(getSettings().getClientSettings().get(ClientSettings.WEB_API_URI));
//TODO: add base64 un-encode when applicable
setBearerToken(getSettings().getClientSettings().get(ClientSettings.BEARER_TOKEN));
if (getBearerToken() != null && getBearerToken().length() > 0) {
LOG.info("Bearer token loaded... first 4 characters: " + getBearerToken().substring(0, 4));
}
setClientId(getSettings().getClientSettings().get(ClientSettings.CLIENT_IDENTIFICATION));
setClientSecret(getSettings().getClientSettings().get(ClientSettings.CLIENT_SECRET));
setAuthorizationUri(getSettings().getClientSettings().get(ClientSettings.AUTHORIZATION_URI));
setTokenUri(getSettings().getClientSettings().get(ClientSettings.TOKEN_URI));
setRedirectUri(getSettings().getClientSettings().get(ClientSettings.REDIRECT_URI));
setScope(getSettings().getClientSettings().get(ClientSettings.CLIENT_SCOPE));
LOG.info("Service root is: " + getServiceRoot());
if (getCommander() == null) {
//create Commander instance
setCommander(new Commander.Builder()
.clientId(getClientId())
.clientSecret(getClientSecret())
.tokenUri(getTokenUri())
.scope(getScope())
.serviceRoot(getServiceRoot())
.bearerToken(getBearerToken())
.useEdmEnabledClient(true)
.build());
}
}
/**
* Resets the state of the test container
*/
public void resetState() {
oDataRawResponse.set(null);
request.set(null);
responseCode.set(null);
responseData.set(null);
initialResponseData.set(null);
rawRequest.set(null);
oDataClientErrorException.set(null);
oDataServerErrorException.set(null);
serverODataHeaderVersion.set(null);
testAppliesToServerODataHeaderVersion.set(false);
}
/**
* Executes HTTP GET request and sets the expected local variables in the WebApiTestContainer
* Handles exceptions and sets response codes as well.
*/
public void executePreparedGetRequest() {
try {
setRawRequest(getCommander().getClient().getRetrieveRequestFactory().getRawRequest(getRequestUri()));
setODataRawResponse(getRawRequest().execute());
setResponseData(TestUtils.convertInputStreamToString(getODataRawResponse().getRawResponse()));
setServerODataHeaderVersion(getODataRawResponse().getHeader(HEADER_ODATA_VERSION).toString());
setResponseCode(getODataRawResponse().getStatusCode());
LOG.info("Request succeeded..." + getResponseData().getBytes().length + " bytes received.");
} catch (ODataClientErrorException cex) {
LOG.debug("ODataClientErrorException caught. Check tests for asserted conditions...");
LOG.debug(cex);
setODataClientErrorException(cex);
setServerODataHeaderVersion(TestUtils.getHeaderData(HEADER_ODATA_VERSION, cex.getHeaderInfo()));
setResponseCode(cex.getStatusLine().getStatusCode());
} catch (ODataServerErrorException ode) {
LOG.debug("ODataServerErrorException thrown in executeGetRequest. Check tests for asserted conditions...");
//TODO: look for better ways to do this in Olingo or open PR
if (ode.getMessage().contains(Integer.toString(HttpStatus.SC_NOT_IMPLEMENTED))) {
setResponseCode(HttpStatus.SC_NOT_IMPLEMENTED);
}
setODataServerErrorException(ode);
} catch (Exception ex) {
fail("ERROR: unhandled Exception in executeGetRequest()!\n" + ex.toString());
}
}
public Settings getSettings() {
return settings.get();
}
public void setSettings(Settings settings) {
this.settings.set(settings);
}
/**
* Gets server metadata in Edm format.
*
* @return
* @implNote the data in this item are cached in the commander once fetched
*/
public Edm getEdm() {
if (edm.get() == null) {
ODataRetrieveResponse<Edm> response = getCommander().prepareEdmMetadataRequest().execute();
responseCode.set(response.getStatusCode());
edm.set(response.getBody());
}
return edm.get();
}
/**
* Gets server metadata in XMLMetadata format.
*
* @return XMLMetadata representation of the server metadata.
* @implNote the data in this item are cached in the commander once fetched
*/
public XMLMetadata getXMLMetadata() {
if (xmlMetadata.get() == null) {
ODataRetrieveResponse<XMLMetadata> response = getCommander().prepareXMLMetadataRequest().execute();
responseCode.set(response.getStatusCode());
xmlMetadata.set(response.getBody());
}
return xmlMetadata.get();
}
public Commander getCommander() {
return commander.get();
}
public void setCommander(Commander commander) {
this.commander.set(commander);
}
public ODataRawResponse getODataRawResponse() {
return oDataRawResponse.get();
}
public void setODataRawResponse(ODataRawResponse oDataRawResponse) {
this.oDataRawResponse.set(oDataRawResponse);
}
public Request getRequest() {
return request.get();
}
public void setRequest(Request request) {
this.request.set(request);
}
public URI getRequestUri() {
return requestUri.get();
}
public void setRequestUri(URI requestUri) {
this.requestUri.set(requestUri);
}
public Integer getResponseCode() {
return responseCode.get();
}
public void setResponseCode(Integer responseCode) {
this.responseCode.set(responseCode);
}
public String getResponseData() {
return responseData.get();
}
public void setResponseData(String responseData) {
this.responseData.set(responseData);
}
public String getInitialResponseData() {
return initialResponseData.get();
}
public void setInitialResponseData(String initialResponseData) {
this.initialResponseData.set(initialResponseData);
}
public ODataRawRequest getRawRequest() {
return rawRequest.get();
}
public void setRawRequest(ODataRawRequest oDataRawRequest) {
this.rawRequest.set(oDataRawRequest);
}
public ODataClientErrorException getODataClientErrorException() {
return oDataClientErrorException.get();
}
public void setODataClientErrorException(ODataClientErrorException oDataClientErrorException) {
this.oDataClientErrorException.set(oDataClientErrorException);
}
public ODataServerErrorException getODataServerErrorException() {
return oDataServerErrorException.get();
}
public void setODataServerErrorException(ODataServerErrorException oDataServerErrorException) {
this.oDataServerErrorException.set(oDataServerErrorException);
}
public String getServerODataHeaderVersion() {
return serverODataHeaderVersion.get();
}
public void setServerODataHeaderVersion(String serverODataHeaderVersion) {
this.serverODataHeaderVersion.set(serverODataHeaderVersion);
}
public Boolean getTestAppliesToServerODataHeaderVersion() {
return testAppliesToServerODataHeaderVersion.get();
}
public void setTestAppliesToServerODataHeaderVersion(Boolean testAppliesToServerODataHeaderVersion) {
this.testAppliesToServerODataHeaderVersion.set(testAppliesToServerODataHeaderVersion);
}
public ODataEntitySetRequest<ClientEntitySet> getClientEntitySetRequest() {
return clientEntitySetRequest.get();
}
public void setClientEntitySetRequest(ODataEntitySetRequest<ClientEntitySet> clientEntitySetRequest) {
this.clientEntitySetRequest.set(clientEntitySetRequest);
}
public ODataRetrieveResponse<ClientEntitySet> getClientEntitySetResponse() {
return clientEntitySetResponse.get();
}
public void setClientEntitySetResponse(ODataRetrieveResponse<ClientEntitySet> clientEntitySetResponse) {
this.clientEntitySetResponse.set(clientEntitySetResponse);
}
public ClientEntitySet getClientEntitySet() {
return clientEntitySet.get();
}
public void setClientEntitySet(ClientEntitySet clientEntitySet) {
this.clientEntitySet.set(clientEntitySet);
}
public String getServiceRoot() {
return serviceRoot.get();
}
public void setServiceRoot(String serviceRoot) {
this.serviceRoot.set(serviceRoot);
}
public String getBearerToken() {
return bearerToken.get();
}
public void setBearerToken(String bearerToken) {
this.bearerToken.set(bearerToken);
}
public String getClientId() {
return clientId.get();
}
public void setClientId(String clientId) {
this.clientId.set(clientId);
}
public String getClientSecret() {
return clientSecret.get();
}
public void setClientSecret(String clientSecret) {
this.clientSecret.set(clientSecret);
}
public String getAuthorizationUri() {
return authorizationUri.get();
}
public void setAuthorizationUri(String authorizationUri) {
this.authorizationUri.set(authorizationUri);
}
public String getTokenUri() {
return tokenUri.get();
}
public void setTokenUri(String tokenUri) {
this.tokenUri.set(tokenUri);
}
public String getRedirectUri() {
return redirectUri.get();
}
public void setRedirectUri(String redirectUri) {
this.redirectUri.set(redirectUri);
}
public String getScope() {
return scope.get();
}
public void setScope(String scope) {
this.scope.set(scope);
}
public String getPathToRESOScript() {
return pathToRESOScript.get();
}
public void setPathToRESOScript(String pathToRESOScript) {
this.pathToRESOScript.set(pathToRESOScript);
}
}

View File

@ -15,59 +15,59 @@ import java.util.LinkedHashMap;
import java.util.Map;
public class Parameters {
private final Map<String, String> parameters;
private final Map<String, String> parameters;
public Parameters() {
parameters = new LinkedHashMap<>();
}
public Parameters() {
parameters = new LinkedHashMap<>();
}
public static Parameters loadFromRESOScript(File file) {
final String PARAMETERS_KEY = "Parameters";
final String NAME_FIELD = "Name";
final String VALUE_FIELD = "Value";
public static Parameters loadFromRESOScript(File file) {
final String PARAMETERS_KEY = "Parameters";
final String NAME_FIELD = "Name";
final String VALUE_FIELD = "Value";
Map<String, String> settings = new LinkedHashMap<>();
Map<String, String> settings = new LinkedHashMap<>();
try {
FileInputStream fileIS = new FileInputStream(file);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(fileIS);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/OutputScript/" + PARAMETERS_KEY + "/node()";
NodeList nodes = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
Node node;
String name, value;
try {
FileInputStream fileIS = new FileInputStream(file);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(fileIS);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/OutputScript/" + PARAMETERS_KEY + "/node()";
NodeList nodes = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
Node node;
String name, value;
for (int i = 0; i < nodes.getLength(); i++) {
node = nodes.item(i);
for (int i = 0; i < nodes.getLength(); i++) {
node = nodes.item(i);
if (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
name = node.getAttributes().getNamedItem(NAME_FIELD).getNodeValue();
value = node.getAttributes().getNamedItem(VALUE_FIELD).getNodeValue();
if (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
name = node.getAttributes().getNamedItem(NAME_FIELD).getNodeValue();
value = node.getAttributes().getNamedItem(VALUE_FIELD).getNodeValue();
settings.put(name, value);
}
}
} catch (Exception e) {
e.printStackTrace();
settings.put(name, value);
}
Parameters parameters = new Parameters();
parameters.getParameters().putAll(settings);
return parameters;
}
} catch (Exception e) {
e.printStackTrace();
}
Parameters parameters = new Parameters();
parameters.getParameters().putAll(settings);
public Map<String, String> getParameters() {
return this.parameters;
}
return parameters;
}
public String getValue(String name) {
return parameters.get(name);
}
public Map<String, String> getParameters() {
return this.parameters;
}
public void putParameter(String name, String value) {
this.parameters.put(name, value);
}
public String getValue(String name) {
return parameters.get(name);
}
public void putParameter(String name, String value) {
this.parameters.put(name, value);
}
}

View File

@ -16,210 +16,225 @@ import java.util.Date;
import java.util.List;
public class Request {
private String requestId;
private String outputFile;
private String url;
private String requestId;
private String outputFile;
private String url;
private Request request;
private Status status;
private Date startDate, endDate;
private Integer httpResponseCode;
private Exception failedRequestException;
private Request request;
private Status status;
private Date startDate, endDate;
private Integer httpResponseCode;
private Exception failedRequestException;
/**
* Public constructor requires both outputFile and url. Remaining Request properties
* may be set individually after Request has been instantiated.
*
* @param outputFile
* @param url
*/
public Request(String url, String outputFile, String requestId) {
setUrl(url);
setOutputFile(outputFile);
setRequestId(requestId);
}
/**
* Public constructor requires both outputFile and url. Remaining Request properties
* may be set individually after Request has been instantiated.
*
* @param outputFile
* @param url
*/
public Request(String url, String outputFile, String requestId) {
setUrl(url);
setOutputFile(outputFile);
setRequestId(requestId);
}
/**
* Provides null handling for getting the requested item
*
* @param name the name of the item to get
* @param node the nod to get the named item from
* @return the named item, if present. Otherwise null
*/
private static String safeGetNamedItem(String name, Node node) {
Node named = name != null && node != null ? node.getAttributes().getNamedItem(name) : null;
return named != null ? named.getNodeValue() : null;
}
/**
* Gets the status of the given request
* @return the status of the request
*/
public Status getStatus() {
return status;
}
/**
* Loads the requests from the given File as an Observable List of Requests
*
* @param file the file containing the requests
* @return an Observable list of requests, or an exception is thrown
*/
public static List<Request> loadFromRESOScript(File file) {
final String REQUESTS_KEY = "Requests";
ArrayList<Request> requests = new ArrayList<>();
/**
* Sets the status for the give request
* @param status the status to set
* @return the current instance of the request
*/
public Request setStatus(Status status) {
this.status = status;
return this;
}
try {
FileInputStream fileIS = new FileInputStream(file);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(fileIS);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/OutputScript/" + REQUESTS_KEY + "/node()";
NodeList nodes = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
Node node;
String outputFile, url, requestId;
Request request;
/**
* Starts request timer
* @return the current request
*/
public Request startTimer() {
startDate = new Date();
return this;
}
for (int i = 0; i < nodes.getLength(); i++) {
node = nodes.item(i);
/**
* Stops request timer
* @return the current request
*/
public Request stopTimer() {
endDate = new Date();
return this;
}
if (node.getNodeType() == Node.ELEMENT_NODE) {
outputFile = safeGetNamedItem(FIELDS.OUTPUT_FILE, node);
url = safeGetNamedItem(FIELDS.URL, node);
requestId = safeGetNamedItem(FIELDS.REQUEST_ID, node);
/**
* Gets the elapsed time the request took to run
* @return the elapsed time of the request in milliseconds
*/
public long getElapsedTimeMillis() {
return endDate != null && startDate != null ? endDate.getTime() - startDate.getTime() : 0L;
}
/**
* Sets the exception for a given request
* @param failedRequestException the exception that was thrown when the request was executed
*/
public void setFailedRequestException(Exception failedRequestException) {
this.failedRequestException = failedRequestException;
}
/**
* HTTP Response code getter
* @return an Integer representing the response code
*/
public Integer getHttpResponseCode() {
return httpResponseCode;
}
/**
* HTTP Response code setter
* @param httpResponseCode an Integer representing the HTTP Response code
*/
public void setHttpResponseCode(Integer httpResponseCode) {
this.httpResponseCode = httpResponseCode;
}
/**
* An enumeration of request status options
*/
public enum Status {
STARTED, SUCCEEDED, FAILED, SKIPPED
}
/**
* Provides null handling for getting the requested item
* @param name the name of the item to get
* @param node the nod to get the named item from
* @return the named item, if present. Otherwise null
*/
private static String safeGetNamedItem(String name, Node node) {
Node named = name != null && node != null ? node.getAttributes().getNamedItem(name) : null;
return named != null ? named.getNodeValue() : null;
}
/**
* Loads the requests from the given File as an Observable List of Requests
* @param file the file containing the requests
* @return an Observable list of requests, or an exception is thrown
*/
public static List<Request> loadFromRESOScript(File file) {
final String REQUESTS_KEY = "Requests";
ArrayList<Request> requests = new ArrayList<>();
try {
FileInputStream fileIS = new FileInputStream(file);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(fileIS);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/OutputScript/" + REQUESTS_KEY + "/node()";
NodeList nodes = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
Node node;
String outputFile, url, requestId;
Request request;
for (int i = 0; i < nodes.getLength(); i++) {
node = nodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
outputFile = safeGetNamedItem(FIELDS.OUTPUT_FILE, node);
url = safeGetNamedItem(FIELDS.URL, node);
requestId = safeGetNamedItem(FIELDS.REQUEST_ID, node);
request = new Request(url, outputFile, requestId);
requests.add(request);
}
}
} catch (Exception e) {
e.printStackTrace();
request = new Request(url, outputFile, requestId);
requests.add(request);
}
return requests;
}
} catch (Exception e) {
e.printStackTrace();
}
return requests;
}
/**
* Gets the given request by Id, if present.
* @return either the request Id or null if none was passed. May be null.
*/
public String getRequestId() {
return requestId;
}
/**
* Gets the status of the given request
*
* @return the status of the request
*/
public Status getStatus() {
return status;
}
/**
* Sets the given request Id, if present.
* @param requestId the request Id to set.
*/
public void setRequestId(String requestId) {
this.requestId = requestId;
}
/**
* Sets the status for the give request
*
* @param status the status to set
* @return the current instance of the request
*/
public Request setStatus(Status status) {
this.status = status;
return this;
}
/**
* Output file getter
* @return the name of the output file for the request
*/
public String getOutputFile() {
return outputFile;
}
/**
* Starts request timer
*
* @return the current request
*/
public Request startTimer() {
startDate = new Date();
return this;
}
/**
* Output file setter
* @param outputFile the name of the output file for the request (required, not null)
*/
private void setOutputFile(String outputFile) {
this.outputFile = outputFile;
}
/**
* Stops request timer
*
* @return the current request
*/
public Request stopTimer() {
endDate = new Date();
return this;
}
/**
* URL getter
* @return the URL for the request, or null
*/
public String getUrl() {
return url;
}
/**
* Gets the elapsed time the request took to run
*
* @return the elapsed time of the request in milliseconds
*/
public long getElapsedTimeMillis() {
return endDate != null && startDate != null ? endDate.getTime() - startDate.getTime() : 0L;
}
/**
* URL setter
* @param url the URL for the request, or null
*/
private void setUrl(String url) {
this.url = url;
}
/**
* Sets the exception for a given request
*
* @param failedRequestException the exception that was thrown when the request was executed
*/
public void setFailedRequestException(Exception failedRequestException) {
this.failedRequestException = failedRequestException;
}
/**
* Represents the known fields that can be in a serialized Request
*/
private static final class FIELDS {
static final String OUTPUT_FILE = "OutputFile";
static final String URL = "Url";
static final String REQUEST_ID = "RequestId";
}
/**
* HTTP Response code getter
*
* @return an Integer representing the response code
*/
public Integer getHttpResponseCode() {
return httpResponseCode;
}
/**
* HTTP Response code setter
*
* @param httpResponseCode an Integer representing the HTTP Response code
*/
public void setHttpResponseCode(Integer httpResponseCode) {
this.httpResponseCode = httpResponseCode;
}
/**
* Gets the given request by Id, if present.
*
* @return either the request Id or null if none was passed. May be null.
*/
public String getRequestId() {
return requestId;
}
/**
* Sets the given request Id, if present.
*
* @param requestId the request Id to set.
*/
public void setRequestId(String requestId) {
this.requestId = requestId;
}
/**
* Output file getter
*
* @return the name of the output file for the request
*/
public String getOutputFile() {
return outputFile;
}
/**
* Output file setter
*
* @param outputFile the name of the output file for the request (required, not null)
*/
private void setOutputFile(String outputFile) {
this.outputFile = outputFile;
}
/**
* URL getter
*
* @return the URL for the request, or null
*/
public String getUrl() {
return url;
}
/**
* URL setter
*
* @param url the URL for the request, or null
*/
private void setUrl(String url) {
this.url = url;
}
/**
* An enumeration of request status options
*/
public enum Status {
STARTED, SUCCEEDED, FAILED, SKIPPED
}
/**
* Represents the known fields that can be in a serialized Request
*/
private static final class FIELDS {
static final String OUTPUT_FILE = "OutputFile";
static final String URL = "Url";
static final String REQUEST_ID = "RequestId";
}
}

View File

@ -1,7 +1,10 @@
package org.reso.models;
import java.io.File;
import java.util.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* The settings class contains all the settings a server can have, which currently means the following:
@ -9,7 +12,9 @@ import java.util.*;
* * parameters - arbitrary collection of user-defined parameters
* * requests - list of requests, one filter string per request, corresponding to a saved search
*/
public class Settings {
public class Settings {
public static final String CLIENT_SETTING_PREFIX = "ClientSettings_";
public static final String PARAMETER_PREFIX = "Parameter_";
private ClientSettings clientSettings;
private Parameters parameters;
private Map<Request, Request> requests;
@ -26,7 +31,8 @@ public class Settings {
* @param settings the settings to write.
* @param filename the filename to save settings to.
*/
public static void saveToRESOScript(Settings settings, String filename) { /* TODO */ ; }
public static void saveToRESOScript(Settings settings, String filename) { /* TODO */
}
/**
* Loads and returns settings from the given file.
@ -46,9 +52,6 @@ public class Settings {
return settings;
}
public static final String CLIENT_SETTING_PREFIX = "ClientSettings_";
public static final String PARAMETER_PREFIX = "Parameter_";
/**
* Resolves the parameters in request with parameters.
*
@ -62,8 +65,9 @@ public class Settings {
/**
* Resolves URIs containing special RESOScript parameters of the form *Parameter_X* and *ClientSettings_Y*
*
* @param parameterString the parameter string to resolve, possibly containing nested parameter settings
* @param settings the settings to use to resolve the parameters
* @param settings the settings to use to resolve the parameters
* @return the resolved parameter string
*/
public static String resolveParametersString(String parameterString, Settings settings) {
@ -128,14 +132,26 @@ public class Settings {
/**
* Requests getter.
*
* @return The request map that was loaded, indexed by request name.
*/
public Map<Request, Request> getRequests() {
return requests;
}
/**
* Requests setter.
*
* @param requests a list of requests to create the request map from
*/
private void setRequests(List<Request> requests) {
this.requests = new LinkedHashMap<Request, Request>();
requests.forEach(request -> this.requests.put(request, request));
}
/**
* Requests getter.
*
* @return The request map that was loaded, indexed by request name.
*/
public Request getRequestById(String requestId) {
@ -159,14 +175,4 @@ public class Settings {
public List<Request> getRequestsAsList() {
return new ArrayList<>(requests.values());
}
/**
* Requests setter.
*
* @param requests a list of requests to create the request map from
*/
private void setRequests(List<Request> requests) {
this.requests = new LinkedHashMap<Request, Request>();
requests.forEach(request -> this.requests.put(request, request));
}
}