From 598f38921fa195af007d7f28e3cc40de1904575f Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Wed, 6 Sep 2017 16:20:16 -0400 Subject: [PATCH] Start Environment layer --- stix2/environment.py | 64 ++++++++++++++++++++++++++++++++++++--- stix2/sources/__init__.py | 16 +++++----- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/stix2/environment.py b/stix2/environment.py index f855755..91f0676 100644 --- a/stix2/environment.py +++ b/stix2/environment.py @@ -1,11 +1,10 @@ import copy +from .sources import CompositeDataSource + class ObjectFactory(object): - """Object Factory - - Used to easily create STIX objects with default values for certain - properties. + """Easily create STIX objects with default values for certain properties. Args: created_by_ref: Default created_by_ref value to apply to all @@ -66,3 +65,60 @@ class ObjectFactory(object): properties.update(**kwargs) return cls(**properties) + + +class Environment(object): + """ + + Args: + factory (ObjectFactory): Factory for creating objects with common + defaults for certain properties. + store (DataStore): Data store providing the source and sink for the + environment. + source (DataSource): Source for retrieving STIX objects. + sink (DataSink): Destination for saving STIX objects. + Invalid if `store` is also provided. + """ + + def __init__(self, factory=None, store=None, source=None, sink=None): + self.factory = factory + self.source = CompositeDataSource() + if store: + self.source.add_data_source(store.source) + self.sink = store.sink + if source: + self.source.add_data_source(source) + if sink: + if store: + raise ValueError("Data store already provided! Environment may only have one data sink.") + self.sink = sink + + def create(self, *args, **kwargs): + """Use the object factory to create a STIX object with default property values. + """ + return self.factory.create(*args, **kwargs) + + def get(self, *args, **kwargs): + """Retrieve the most recent version of a single STIX object by ID. + """ + return self.source.get(*args, **kwargs) + + def all_versions(self, *args, **kwargs): + """Retrieve all versions of a single STIX object by ID. + """ + return self.source.all_versions(*args, **kwargs) + + def query(self, *args, **kwargs): + """Retrieve STIX objects matching a set of filters. + """ + return self.source.query(*args, **kwargs) + + def add_filter(self, *args, **kwargs): + """Add a filter to be applied to all queries for STIX objects from this environment. + """ + return self.source.add_filter(*args, **kwargs) + + def add(self, *args, **kwargs): + """Store a STIX object. + """ + return self.sink.add(*args, **kwargs) diff --git a/stix2/sources/__init__.py b/stix2/sources/__init__.py index b50fd1d..08063f5 100644 --- a/stix2/sources/__init__.py +++ b/stix2/sources/__init__.py @@ -5,7 +5,7 @@ Classes: DataStore DataSink DataSource - STIXCommonPropertyFilters + CompositeDataSource TODO:Test everything @@ -226,7 +226,7 @@ class DataSource(object): self.filters.add(filter) def apply_common_filters(self, stix_objs, query): - """Evaluates filters against a set of STIX 2.0 objects + """Evaluate filters against a set of STIX 2.0 objects. Supports only STIX 2.0 common property fields @@ -300,11 +300,10 @@ class DataSource(object): class CompositeDataSource(DataSource): - """Composite Data Source + """Controller for all the defined/configured STIX Data Sources. - Acts as a controller for all the defined/configured STIX Data Sources - e.g. a user can define n Data Sources - creating Data Source (objects) - for each. There is only one instance of this for any python STIX 2.0 + E.g. a user can define n Data Sources - creating Data Source (objects) + for each. There is only one instance of this for any Python STIX 2.0 application. Attributes: @@ -314,8 +313,7 @@ class CompositeDataSource(DataSource): """ def __init__(self): - """ - Creates a new STIX Data Source. + """Create a new STIX Data Source. Args: name (str): A string containing the name to attach in the @@ -448,6 +446,8 @@ class CompositeDataSource(DataSource): to the Composite Data Source """ + if not isinstance(data_sources, list): + data_sources = [data_sources] for ds in data_sources: if issubclass(ds.__class__, DataSource): if ds.id in self.data_sources: