-
Notifications
You must be signed in to change notification settings - Fork 14
Aggregate attributes from remote adapters #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| attributeConnector.setIsActive(true); | ||
| attributeConnector.setMaxCachedIntervalMinutes(60); | ||
| attributeConnector.setAdapters(new HashSet<>(Collections.singletonList( | ||
| new AttributeAdapterConnection("https://acs-asset-adapter.run.aws-usw02-dev.ice.predix.io/v1/attribute", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please parameterize the adapter settings. settings will change for each env
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| new HttpEntity<>(attributeConnector, httpHeaders), AttributeConnector.class); | ||
| } | ||
|
|
||
| private void setupPredixAcs() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can these 3 methods can be shared between different integ tests - maybe in a new version of createTestZone method, which tests can start using over time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't refactored this yet but we can as part of this story or maybe another one?
| } | ||
|
|
||
| this.zone = this.zoneHelper.createTestZone(this.acsAdminRestTemplate, this.acsZone1Name, this.registerWithZac); | ||
| this.configureAttributeConnector(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is the data in the adapter populated ? please add it as part of this test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (Asset data is now configured/deconfigured in this test class)
|
|
||
| private OAuth2RestTemplate getAdapterOauth2RestTemplate( | ||
| final AttributeAdapterConnectionEntity attributeAdapterConnectionEntity) { | ||
| ClientCredentialsResourceDetails clientCredentials = new ClientCredentialsResourceDetails(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rest template should be cached in this object, instead of creating on every request. This will prevent a "get token" on every request
- pls review anything else which can be done once or at construction time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| ResponseEntity<AttributesResponse> attributesResponse; | ||
| try { | ||
| attributesResponse = this.getAttributesFromAdapter(adapterUrl, adapterEntity, adapterRestTemplate); | ||
| } catch (final RestClientException e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
catch 'Throwable' here to ensure evaluation service can handle the AttributeRetrievalException
- Lets make sure there is a test which asserts that policy eval service handles any exception and returns a INDETERMINATE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Also there already seems to be a test that asserts that Effect.INDETERMINATE is produced when a RuntimeException exception is thrown: PolicyEvaluationServiceTest#testPolicyEvaluationExceptionHandling
|
|
||
| // TODO: Reset the TTL for the policy evaluation cache key concerning this resource to: | ||
| // total customer TTL - this.attributeCache.getConfiguredTtlInSeconds() | ||
| //long policyEvalDecisionCacheTtlInSeconds = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Policy eval simply constructs a key and call the decision cache. When to use the cached decision will have to be in the decision cache layer. The decision cache does not have a TTL configured on the cache itself - see AbstractPolicyEvaluationCache.isCachedRequestInvalid - after looking up both the decision and the lastModifiedTime for the resource(& subject) involved, it decides to use the decision or not.
We need to modify this code path to:
- check if resource or subject connector is enabled
- if yes, the decision cache should be invalidated if its been cached for >= (connector.CacheInterval - attributeCacehInterval - 1 min for safety).
This is one way to make this functional - we should reconsider the relationship between decision and attribute cache when we implement a real cache for attributes. Maybe one abstraction should provide the decision Or attributes (if the decision is stale).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, implemented this; a related test hasn't been added yet because it would be time-based and thus error prone.
| Assert.assertNull(this.adapterRepository.findOne(adapterId)); | ||
| } | ||
|
|
||
| @Test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why remove ? isnt this the expected behavior right now ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been re-introduced.
| .thenThrow(AttributeRetrievalException.class); | ||
|
|
||
| PolicyEvaluationResult evalResult = this.evaluatePolicy(); | ||
| Assert.assertEquals(evalResult.getEffect(), Effect.INDETERMINATE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test would be better if you do a successful PERMIT first, then only mock the rule above to produce a INDETERMIANTE.
Also, in this case eval service should set a appropriate message in PoliceEvaluationResult.message indicating some problem with the adapter, along with reference info for the adapter. Just enough info, so the end-user can pass on the reference to service owner who is using ACS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There already is a test for a successful Effect.PERMIT: PolicyEvaluationWithAttributeReaderTest#testPolicyEvaluation so not sure how adding another one here would add value.
Also the adapter endpoint, UAA token URL and UAA client ID are added as part of PolicyEvaluationResult.message.
| return this.privilegeServiceSubjectAttributeReader; | ||
| } | ||
|
|
||
| return new ExternalSubjectAttributeReader(zone, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This factory needs to make sure that a subject or resource externalreader is only created once for each zone.
- also need to check isActive property on the connector, once its added to the entity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (uses maps keyed on the zone ID). The isActive property is now also checked.
55f8438 to
1522538
Compare
| public class PolicyEvaluationWithAttributeConnectorIT extends AbstractTestNGSpringContextTests { | ||
|
|
||
| @Value("${ZONE1_NAME:testzone1}") | ||
| private String acsZone1Name; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you need 3 acs zones for this test ? Also, pls use a unique zone name to allow concurrent execution with other integ tests. (now that we dont use sub-domain routing, any zone name can be provisioned on the fly)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Point taken.. removed all but 1 zone. If we go with a separate integration test suite for connector-related policy evaluation integration tests, we can create a unique zone then but since this currently runs as part of the existing integration test suite I'm reusing a zone.
|
discussed this with anubhav: |
ac38a6f to
e12ef94
Compare
b80b645 to
0fad616
Compare
|
@sanjeevchopra: we should probably create a separate story to push the asset adapter as part of |
| private OAuth2RestTemplate assetRestTemplate; | ||
| private boolean registerWithZac; | ||
| private URI resourceAttributeConnectorUrl; | ||
| private URI resourceAttributeConnectorUrl = URI.create(this.zoneHelper.getAcsBaseURL() + "/v1/resource/connector"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will throw a NullPointerException when the test is run (or not run tests at all) since this.zoneHelper isn't initialized yet. We should move this initialization to the @BeforeClass method below.
Also the connector URI is /v1/connector/resource :) . It might just be better to use AcsApiUriTemplates.V1 + AcsApiUriTemplates.RESOURCE_CONNECTOR_URL to construct the URI path like before so that we only have to make a change in one place.
| public class AttributeConnector { | ||
| private boolean isActive; | ||
|
|
||
| @JsonProperty(defaultValue="480", required=false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this will actually work.. Jackson's core databind currently only uses defaultValue for documenting the expected default value of the property instead of actually enforcing it. If you want to keep this, we need to also change the actual assignment to use a default value like: private int maxCachedIntervalMinutes = 480;
|
|
||
| @Test(dataProvider = "adapterStatusesAndResultingEffects") | ||
| public void testPolicyEvaluationWithAdapters(final boolean adapterActive, final Effect effect) throws Exception { | ||
| HttpHeaders httpHeaders = this.getHeadersWithAcsZoneId(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the zone ID doesn't change throughout the test, it's more efficient to instantiate the zone headers once and use them instead of constructing multiple instances by calling zoneHeader() multiple times
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is a test, I gave precedence readability over efficiency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we get both with: HttpHeaders zoneHeaders = this.zoneHeader(); ?
| String uaaClientId = attributeAdapterConnectionEntity.getUaaClientId(); | ||
| String uaaClientSecret = attributeAdapterConnectionEntity.getUaaClientSecret(); | ||
|
|
||
| Integer key = new HashCodeBuilder().append(uaaTokenUrl).append(uaaClientId).append(uaaClientSecret) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better to implement hashcode in AdapterConnection class and use the object itself as the key, so the key can be leveraged anywhere. plus its better encapsulation
c183c35 to
5c86c4a
Compare
…tes from connectors configured in current zone. Signed-off-by: Sanjeev Chopra <[email protected]> Signed-off-by: Frank Gasparovic <[email protected]>
|
Pull request build is clean - integration-tests # 318-321 |
No description provided.