-
Notifications
You must be signed in to change notification settings - Fork 14
US87160: Caching-related abstractions for resource/subject attribute readers #93
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
FrankGasparovic
left a comment
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.
Looks good
| <NO_READ_ONLY_USER_PASSWORD>${NO_READ_ONLY_USER_PASSWORD}</NO_READ_ONLY_USER_PASSWORD> | ||
| <ZAC_CLIENT_SECRET>${ZAC_CLIENT_SECRET}</ZAC_CLIENT_SECRET> | ||
| </systemPropertyVariables> | ||
| <excludes> |
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.
Add ACSMetering until we figure out how to fix that 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.
Was added as part of DE22023
| private static final String ZONE = "test-zone"; | ||
| private static final String RESOURCE_ID = "aircraftPart/13a71359-db68-4602-aac5-a8fa401c3194"; | ||
| private static final String ASSET_ADAPTER_URI = "http://localhost:8080/v1/attribute/"; | ||
| private static final String ASSET_ATTRIBUTES_JSON = |
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.
Store JSON in src/test/resources like we do for other integration tests
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 (however this file has been moved out to another branch)
| import com.ge.predix.acs.attribute.connectors.ResourceAttributeConnector; | ||
| import com.ge.predix.acs.attribute.connectors.SubjectAttributeConnector; | ||
| import com.ge.predix.acs.attribute.readers.ExternalResourceAttributeReader; | ||
| import com.ge.predix.acs.attribute.readers.ExternalSubjectAttributeReader; |
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.
Should we stick to calling everything connectors or readers? We have these ExternalResourceAttributeReader and ExternalSubjectAttributeReader, but the test is called PolicyEvaluationWithAttributeConnectorTest.java, and in the JPA story we created the AttributeConnectorEntity @sanjeevchopra. Just seems like we are making it confusing for no reason.
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, @FrankGasparovic lets discuss naming tomorrow.
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, we're sticking to the Reader suffix for connector-related internal abstractions and the Connector suffix for external abstractions
irinaepshteyn
left a comment
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.
These are my initial comments. I will continue reviewing...
acs-integration-tests/pom.xml
Outdated
| </profile> | ||
|
|
||
| <profile> | ||
| <id>redis</id> |
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 we added another profile, please update (or add a story to update) https://github.build.ge.com/predix/acs-ci-config/blob/master/AcsTestsReadme.md
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.
In the past it was decided to place test reports outside of target directory so reports are not removed by 'mvn clean' and retained by Jenkins for each profile. Refer to reportsDirectory and summaryFile in the failsafe plugin configuration for, for example, public profile.
It might not be relevant any longer since each profile is run by the separate Jenkins job now.
We need to decide if we still want to maintain custom output directories and be consistent in every profile.
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.
Added changes to AcsTestsReadme.md in the master branch of the acs-ci-config Git repo. Also these changes to add the redis Maven profile have been pulled out to another branch but when I re-introduce it I'll look into how to standardize the test output directories.
| <excludes> | ||
| <exclude>**/ExternalResourceAttributeReaderIT.java</exclude> | ||
| <exclude>**/NonHierarchical*IT.java</exclude> | ||
| </excludes> |
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 for acceptance profile we only execute single ACSAcceptanceIT test, excludes section is not needed. Please remove the whole section.
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
| } | ||
|
|
||
| public Set<Attribute> getAttributesFromAdapter(final String zoneId, final String resourceId) { | ||
| // TODO: Add an inline call to the Asset Adapter based on configuration |
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.
Could we change it to private?
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.
Made it package-private to allow testing
| } | ||
|
|
||
| public String getZoneId() { | ||
| return ((ZoneOAuth2Authentication) SecurityContextHolder.getContext().getAuthentication()).getZoneId(); |
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.
Could we change it to private?
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.
Made it package-private to allow testing
irinaepshteyn
left a comment
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.
Additional review comments.
| import com.ge.predix.acs.policy.evaluation.cache.InMemoryPolicyEvaluationCache; | ||
|
|
||
| public class ExternalResourceAttributeReaderTest { | ||
|
|
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 is written to test mostly InMemoryAttributeCache and not ExternalResourceAttributeReader. It has to be renamed to com.ge.predix.acs.attribute.cache.InMemoryAttributeCacheTest.
For testing ExternalResourceAttributeReader it should be sufficient to mock cache to return no attributes and mock getAttributesFromAdapter to return a set of attributes and compare what's returned from actual getAttributes.
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
| Set<Attribute> cachedAttributes = this.externalResourceAttributeReader.getAttributes(RESOURCE_ID); | ||
|
|
||
| for (Attribute cachedAttribute : cachedAttributes) { | ||
| Assert.assertTrue(attributes.contains(cachedAttribute)); |
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.
Instead of 'for' loop could use Assert.assertTrue(attributes.containsAll(cachedAttributes)) or Assert.assertEquals(attributes, cachedAttributes);
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
| Long ttl = this.redisTemplate.getExpire(resourceAttributesKey, TimeUnit.SECONDS); | ||
| Assert.assertTrue(ttl > 0L && ttl <= this.attributeCache.getConfiguredTtl()); | ||
| } | ||
| } |
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.
We need to add another IT: PolicyEvalCachingWithExternalResourceAttributeReaderIT to assert that policy decision is reevaluated if attributes cache is expired and attributes are refreshed.
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 be added as part of US87156
| import com.ge.predix.acs.policy.evaluation.cache.AbstractPolicyEvaluationCache; | ||
|
|
||
| @Component | ||
| public abstract class AbstractAttributeCache implements AttributeCache { |
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 class does not need to know the difference between subject of resource. Just (id, attributes)
- Both resource and subject connector will have one instance of each of this cache
- On that note most of the connector implementation will be subject/resource agnostic.
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.
Discussed this with @anubhavi25 . Added notes in redis caching story.
- this pull request will be limited to in-memory caching only
- initially a common cache across zones is ok, however we need to limit the storage impact on ACS. Please add 2 env vars - MAX_ATTRIBUTE_CACHE_ENTRIES (default 10K), MAX_ATTRIBUTES_PER_ID (default 100?)
- we should adjust the mem allocation to ACS accordingly ~ +1gb (1k per attribute x 100 attributes per user/resource x 10,000 users/resources)
- key should be zone+id. One cache each for attribute and subject connectors.
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. We can make the relevant config changes to bump up the app memory in acs-ci-config as part of US87168. Also, as discussed, Redis-related changes will be pulled out to the US87168 branch.
|
|
||
| import com.ge.predix.acs.model.Attribute; | ||
|
|
||
| public interface AttributeCache { |
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.
Dont see much value in this interface. Just make this the abstract class?
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.
Removed in lieu of AbstractAttributeCache
|
|
||
| public abstract long getExpiration(String key); | ||
|
|
||
| public abstract long getConfiguredTtl(); |
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 add time unit to the method name
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
|
|
||
| public abstract Set<Attribute> get(String key); | ||
|
|
||
| public abstract long getExpiration(String key); |
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 add time unit to the method name
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 (renamed this to getRemainingTtlInSeconds)
service/pom.xml
Outdated
| <artifactId>jedis</artifactId> | ||
| <version>${jedis.version}</version><!--$NO-MVN-MAN-VER$--> | ||
| </dependency> | ||
| <dependency> |
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 check with Anurag on process to get new dependencies approved.
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.
Now using EhCache which, according to Anurag, is under Apache licensing
| import java.util.Set; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| import org.codehaus.jackson.map.ObjectMapper; |
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.
pls revert changes to this package
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
| Mockito.doReturn(ZONE).when(this.externalResourceAttributeReader).getZoneId(); | ||
| Set<Attribute> cachedAttributes = this.externalResourceAttributeReader.getAttributes(RESOURCE_ID); | ||
|
|
||
| for (Attribute cachedAttribute : cachedAttributes) { |
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.
use equals()
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
|
|
||
| @Test | ||
| public void testGetAttributes() throws Exception { | ||
| Set<Attribute> attributes = Collections.singleton( |
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.
expectedAttributes
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
| Mockito.doReturn(attributes).when(this.externalResourceAttributeReader) | ||
| .getAttributesFromAdapter(ZONE, RESOURCE_ID); | ||
| Mockito.doReturn(ZONE).when(this.externalResourceAttributeReader).getZoneId(); | ||
| Set<Attribute> cachedAttributes = this.externalResourceAttributeReader.getAttributes(RESOURCE_ID); |
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.
actualAttributes
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
| import com.ge.predix.acs.attribute.connectors.ResourceAttributeConnector; | ||
| import com.ge.predix.acs.attribute.connectors.SubjectAttributeConnector; | ||
| import com.ge.predix.acs.attribute.readers.ExternalResourceAttributeReader; | ||
| import com.ge.predix.acs.attribute.readers.ExternalSubjectAttributeReader; |
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, @FrankGasparovic lets discuss naming tomorrow.
Addressed feedback and replied to comments
|
@sanjeevchopra @irinaepshteyn please review again as there were non-trivial changes in the last commit (i.e. removed Redis-related changes, moved to EhCache and incorporated cache-related constraints) |
…readers Signed-off-by: Sanjeev <[email protected]> Signed-off-by: Frank <[email protected]>
No description provided.