9.2 KiB
Typical Data Mining Scenarios
[[TOC]]
Adding a new Data Mining Bundle
- Add a new java project bundle according to the Typical Development Scenarios
- Add the necessary dependencies to the
MANIFEST.MFcom.sap.sse(for the string messages)com.sap.sse.dataminingcom.sap.sse.datamining.shared
- Create an
Activatorfor the new data mining bundle and provide aDataMiningBundleServiceto the OSGi-Context (see Registration and Deregistration of Data Mining Bundles for detailed information)- This can be done by extending the
AbstractDataMiningActivatorand implementing it's abstract methods - Or by implementing your own
DataMiningBundleServiceand register it as OSGi-Service
- This can be done by extending the
- Prepare the string messages
- Create the new source folder
resources - Add the package
<string messages package name>toresources - Create empty properties files for each supported language with the name scheme
<string messages base name>_<locale acronym> - Create a
ResourceBundleStringMessagesin theDataMiningBundleService- The
ResourceBundleStringMessagesneeds the resource base name, which should be<string messages package name>/<string messages base name> - A reference to this
ResourceBundleStringMessagesshould be returned by the methodgetStringMessages()
- The
- Create the new source folder
Adding an absolute new Data Type
A data type is an atomic unit on which the processing components operate. A data type is normally based on a domain element (like GPSFixMoving or TrackedLegOfCompetitor) and provides contextual information about it (like the name of the regatta or race) via Functions.
Create the necessary Data Types
- Create an interface for the domain element. The naming convention for data type interfaces is
Has<domain element name>Context.- If
TrackedLegOfCompetitorwould be the domain element, then the name of the data type interface should beHasTrackedLegOfCompetitorContext.
- If
- Create a data type interface for the steps from the data source to the domain element
- In the case of the
TrackedLegOfCompetitorthe steps would beRacingEventServiceLeaderboardGroupLeaderboardTrackedRaceTrackedLegTrackedLegOfCompetitor
- This isn't mandatory for the framework to work, but it improves its performance, because it's possible to build a processor chain, that filters after each step.
- In the case of the
- Add the data type interfaces to the
Classesreturn by the methodgetClassesWithMarkedMethods()of theDataMiningBundleService. - Add methods to get the contextual information and annotate them, so that they get registered as functions.
- To get the contextual data of a higher level data type interface annotate the getter for this interface with
@Connector(scanForStatistics=false). - There's currently no parameter support for functions, except for signatures exactly like
(Locale, ResourceBundleStringMessages). - Cycles in the graph of annotated methods aren't supported and would result in an infinite loop during the function registration.
- See Data Mining Functions for detailed information about the annotations.
- To get the contextual data of a higher level data type interface annotate the getter for this interface with
- Create implementations for the data type interfaces. The naming convention for data type classes is
<domain element name>WithContext.- If
TrackedLegOfCompetitorwould be the domain element, then the name of the data type class should beTrackedLegOfCompetitorWithContext.
- If
Implement the Retrieval Processors and define the Retriever Chain
- Add a
DataSourceProviderto theDataMiningBundleService, if it doesn't contain one for the data source of the data type. - Implement a retrieval processor for each data type.
- Retrieval processors should extend
AbstractRetrievalProcessor. - Retrieval processors used by retriever chains need a constructor with the signature
(ExecutorService, Collection<Processor<ResultType, ?>>, int). - A retrieval processor describes how to get from the input data type (like
RacingEventServiceorTrackedRace) to the result data type (likeTrackedLeg) with the methodretrieveData.
- Retrieval processors should extend
- Create a
DataRetrieverChainDefinitionand add it to theDataMiningBundleService.- A retriever chain is created with its methods
startWith,addAfterandendWith, that addClassesof your retrieval processors to the chain. - Each method has a parameter for the
Classof the retrieved data type of the next step and some also have a parameter for theClassof the retrieval processor of the previous step to ensure type safety. - Each method has a parameter for a message key, that is needed for the internationalization of the chain.
- The call order of these methods has to match
startWith addAfter* endWithor an exception will be thrown. - Every retrieval processor needs a constructor with the signature
(ExecutorService, Collection<Processor<ResultType, ?>>, int)or an exception will be thrown. - See Defining and building a Data Retriever Chain for examples and more detailed information.
- A retriever chain is created with its methods
Adding a new Data Type with a reusable Retriever Chain
- Create the necessary Data Types according to this.
- Implement a retrieval processor for each data type according to the first step of this.
- Split the existing retriever chain and diverge it two retriever chains.
- The split point should be the last retrieval processor, that is shared by the retriever chains
- If there would be these two retriever chains
than existing retriever chain should be splitted after the retrieval processor for the `TrackedRaces`.Existing New `RacingEventService`
`LeaderboardGroup`
`Leaderboard`
`TrackedRace`
`TrackedLeg`
`TrackedLegOfCompetitor``RacingEventService`
`LeaderboardGroup`
`Leaderboard`
`TrackedRace`
`MarkPassing`
- If there would be these two retriever chains
- To split an existing retriever chain, create a new one after the split point with the usage of the existing one. Then move the
addAfterandendWithcalls to the new retriever chain. The first part of the split retriever chain can now be used to create the retriever chain for the new data type.- Note, that it's not necessary to call
startWith, if a retriever chain is used to create a new one.
- Note, that it's not necessary to call
- In pseudo code would this look like this:
Before:
- The split point should be the last retrieval processor, that is shared by the retriever chains
RetrieverChain trackedLegRetrieverChain = new RetrieverChain(RacingEventService.class, TrackedLegOfCompetitor.class); trackedLegRetrieverChain.startWith(LeaderboardGroupRetrievalProcessor.class); trackedLegRetrieverChain.addAfter(LeaderboardRetrievalProcessor.class); trackedLegRetrieverChain.addAfter(TrackedRaceRetrievalProcessor.class); trackedLegRetrieverChain.addAfter(TrackedLegRetrievalProcessor.class); trackedLegRetrieverChain.endWith(TrackedLegOfCompetitorRetrievalProcessor.class); After:
RetrieverChain trackedRaceRetrieverChain = new RetrieverChain(RacingEventService.class, TrackedRace.class); trackedLegRetrieverChain.startWith(LeaderboardGroupRetrievalProcessor.class); trackedLegRetrieverChain.addAfter(LeaderboardRetrievalProcessor.class); trackedLegRetrieverChain.endWith(TrackedRaceRetrievalProcessor.class); </ br> RetrieverChain trackedLegRetrieverChain = new RetrieverChain(trackedRaceRetrieverChain, TrackedLegOfCompetitor.class); trackedLegRetrieverChain.addAfter(TrackedLegRetrievalProcessor.class); trackedLegRetrieverChain.endWith(TrackedLegOfCompetitorRetrievalProcessor.class); </ br> RetrieverChain markPassingRetrieverChain = new RetrieverChain(trackedRaceRetrieverChain, MarkPassing.class); markPassingRetrieverChain.endWith(MarkPassingRetrievalProcessor.class);
- Ensure, that all retriever chains are added to the
DataMiningBundleService
Include a Type forcefully in the GWT Serialization Policy
It can happen, that a necessary type isn't included in the GWT Serialization Policy, because of the generality of the framework. To enforce the include of a type, the GWT-Service has to use the type in one of its methods. To do this, follow these steps:
- Create a dummy class in a shared bundle, if such a dummy class doesn't exist already in the scope of the type.
- For example like
SSEDataMiningSerializationDummy. - The class has to implement
Serializableand should only have a private standard constructor, to prevent an accidental instantiation.
- For example like
- Add a private non-final instance variable of the type to the dummy.
- Add a pseudo method to the GWT-Service, that uses the dummy class, if such a method doesn't exist already.
- For example like
SSEDataMiningSerializationDummy pseudoMethodSoThatSomeSSEDataMiningClassesAreAddedToTheGWTSerializationPolicy().
- For example like
The type will be included in the GWT Serialization Policy, because the GWT-Service has a method, that uses the dummy class, that uses the type.