Execute the following piece of code to connect to the public IncQuery Server demo instance.
If you have non-guest privileges, you may specify your credentials here.
import iqs_jupyter
iqs = iqs_jupyter.connect(
address='https://openmbee.incquery.io',
user='guest',
password='incqueryserverguest'
)
Run the next code block to display the commit selector widget, and use it to browse around the MMS repository. When you've had your fun, make sure to leave it in a state where a commit is selected from the IQS4MMS Demos org, as we have made sure to pre-index and load those commits in the IQS.
commit_selector = iqs.jupyter_tools.mms_commit_selector_widget()
The following piece of code assigns the Python name model
to the MMS commit selected above, and checks whether the model is indeed indexed and loaded by IQS, which is required for the rest of the demo
model = commit_selector.value().to_model_compartment()
if model.is_loaded_by_server(iqs):
print("We may proceed.")
else:
print("Model is not indexed&loaded by IQS, so the next demo steps will not work.")
print(" (Unfortunately, guest users are not allowed to control model indexing.)")
print("Please select another model from the 'IQS4MMS Demos' org.")
First, we define and register a Viatra graph query for computing requirements traceability coverage.
coverage_query_package = "iqs4mms.demo.coverage"
coverage_query_main = "iqs4mms.demo.coverage.packageCoverage"
coverage_query_code = '''
// SECTION 1: main query
/*
* Associates a UML package with
* - the total number of transitively contained SysML Blocks, and
* - the number of strongly and weakly covered blocks among them
*/
incremental pattern packageCoverage(
pack: Package,
totalBlocks: java Integer,
stronglyCovered: java Integer,
weaklyCovered: java Integer
) {
totalBlocks == count find blockInPackage(_, pack);
stronglyCovered == count find stronglyCoveredBlockInPackage(_, pack);
weaklyCovered == count find weaklyCoveredBlockInPackage(_, pack);
}
// SECTION 2: custom in-house definitions for strong and weak coverage
/*
* Identifies elements that are strongly covered by a requirement.
* This definition may be customized according to in-house concept of strong coverage.
*/
incremental pattern stronglyCovered(element: NamedElement) {
find sysml.Requirement_SatisfiedBy(_, element);
} or {
find sysml.Requirement_VerifiedBy(_, element);
} or {
find sysml.Requirement_TracedTo(_, element);
}
/*
* Identifies elements that are NOT strongly covered,
* but are reachable from a strongly covered element
* using one or more custom propagation steps
*/
incremental pattern weaklyCovered(element: NamedElement) {
find stronglyCovered(otherElement);
find coveragePropagates+(otherElement, element);
neg find stronglyCovered(element);
}
/*
* Defines custom coverage propagation steps, where
* coverage of a 'from' element automatically implies weak coverage of a 'to' element.
* This definition may be customized according to in-house propagation rules.
*/
incremental pattern coveragePropagates(from: NamedElement, to: NamedElement) {
// from container to contained part
Property.owner(part, from);
Property.aggregation(part, ::composite);
TypedElement.type(part, to);
} or {
// from general superclassifier / block to specific block
Generalization.general(gen, from);
Generalization.specific(gen, to);
}
// SECTION 3: helper queries to assemble a report on (transitive) package contents
/*
* Associates SysML Blocks with UML packages directly or indirectly containing them.
*/
incremental pattern blockInPackage(block: Class, pack: Package) {
find sysml.Block(block, _);
Element.owner+(block, pack);
}
/*
* Associates strongly covered Blocks with UML packages directly or indirectly containing them.
*/
incremental pattern stronglyCoveredBlockInPackage(block: Class, pack: Package) {
find stronglyCovered(block);
find blockInPackage(block, pack);
}
/*
* Associates weakly covered Blocks with UML packages directly or indirectly containing them.
*/
incremental pattern weaklyCoveredBlockInPackage(block: Class, pack: Package) {
find weaklyCovered(block);
find blockInPackage(block, pack);
}
'''
from iqs_jupyter import schema
if coverage_query_main not in iqs.queries.list_queries().viatra.query_fq_ns: # skip if already registered
try:
iqs.queries.register_queries_plain_text(coverage_query_code, query_package=coverage_query_package)
display(iqs.query_execution.prepare_standing_queries_on_model_compartment(
schema.QueryFQNListWithModelCompartment(
model_compartment = model,
query_fq_ns = [coverage_query_main]
)))
except:
print("Query registration not available as guest user; please try again in a few minutes")
else:
print("Query is already registered; proceed")
Next, we define and register a Lucene full-text query for finding text notes that suggest incompleteness.
todos_query_package = "iqs.lucene.example"
todos_query_simplename = "todo"
todos_query_code = 'todo\ntbd\nmissing\nincomplete'
todos_query_fqn = "{}.{}".format(todos_query_package, todos_query_simplename)
if todos_query_fqn not in iqs.queries.list_queries().lucene.query_fq_ns: # skip if already registered
try:
display(iqs.queries.register_queries(schema.QueryDefinitionRequest(
query_definitions = [todos_query_code],
package_name = todos_query_package,
query_name = todos_query_simplename,
query_language = 'lucene'
)))
except:
print("Query registration not available as guest user; please try again in a few minutes")
else:
print("Query is already registered; proceed")
Finally, we define and register a SPARQL graph query that selects named elements with too short names.
shortname_query_package = "iqs4mms.demo.sparql"
shortname_query_simplename = "nameTooShort"
shortname_query_code = '''
select ?c ?n where {
?c rdf:type/rdfs:subClassOf* uml:NamedElement .
?c uml:NamedElement.name ?n .
FILTER(0 < STRLEN(?n) && STRLEN(?n) < 5)
}
'''
shortname_query_fqn = "{}.{}".format(shortname_query_package, shortname_query_simplename)
if shortname_query_fqn not in iqs.queries.list_queries().sparql.query_fq_ns: # skip if already registered
try:
iqs.queries.register_queries(schema.QueryDefinitionRequest(
query_definitions = [shortname_query_code],
package_name = shortname_query_package,
query_name = shortname_query_simplename,
query_language = 'sparql'
))
except:
print("Query registration not available as guest user; please try again in a few minutes")
else:
print("Query is already registered; proceed")
from iqs_jupyter import schema
analysis_config_name = "My first analysis configuration with IncQuery Model Analysis Suite"
analysis_config = schema.AnalysisConfiguration(
name = analysis_config_name,
configuration_rules = [
schema.AnalysisRule(
name = "Block coverage ratios per package",
query_fqn = coverage_query_main,
severity = "INFO",
message_template = "Coverage of block"
),
schema.AnalysisRule(
name = "Text occurrences of 'TODO'/'TBD'/'MISSING'/'INCOMPLETE'",
query_fqn = todos_query_fqn,
severity = "INFO",
message_template = "Review this item"
),
schema.AnalysisRule(
name = "Elements with very short name",
query_fqn = shortname_query_fqn,
severity = "WARNING",
message_template = "Element has a very short name (is it abbreviated?)"
)
]
)
configs_with_given_name = [ config
for config in iqs.analysis.list_model_analysis_configurations().model_analysis_configuration_identifiers
if config.configuration_name == analysis_config_name
]
if configs_with_given_name: # found analysis pre-registered
analysis_config = configs_with_given_name[0]
print ("Analysis configuration '{}' found. \nGo on.".format(analysis_config_name))
else: # not found
try:
iqs.analysis.register_model_analysis_configuration(analysis_configuration = analysis_config)
except:
print ("Error: analysis configuration '{}' not found, must be pre-registered for this demo".format(analysis_config_name))
analysis_config_name = "My first analysis configuration with IncQuery Model Analysis Suite"
configs_with_given_name = [ config
for config in iqs.analysis.list_model_analysis_configurations().model_analysis_configuration_identifiers
if config.configuration_name == analysis_config_name
]
if configs_with_given_name:
analysis_config = configs_with_given_name[0]
print ("Analysis configuration '{}' found. \nGo on.".format(analysis_config_name))
else:
print ("Error: analysis configuration '{}' not found, must be pre-registered for this demo".format(analysis_config_name))
from iqs_jupyter import schema
analysis_execution_response = iqs.analysis.run_model_analysis(analysis_execution_request = schema.AnalysisExecutionRequest(
configuration_id = analysis_config.configuration_id,
compartment = model
))
analysis_execution_response
First, connect to the MMS server.
import iqs_jupyter # if not already imported
mms = iqs_jupyter.MMSClient(
address = "https://mms.openmbee.org/alfresco/service",
user = "openmbeeguest",
password= "guest"
)
Below we export an HTML report from the analysis results.
analysis_report_html = '''
<h2>Model Analysis Report</h2>
{}
'''.format(
analysis_execution_response._repr_html_()
)
The generated HTML report can be directly uploaded to MMS. Here we are uploading it to a sandbox document that is publicly writeable.
target_project = 'PROJECT-3cc8325d-f955-424f-8410-4dcdbcae621e'
target_ref = 'master'
target_element = '_hidden_MMS_1575975609494_b5ca9eb4-6db2-41d7-8b93-db9897def885_pei'
mms.element.post_elements(target_project, target_ref,{"elements": [
{"id": target_element, "documentation": analysis_report_html}
]})
The uploaded report is available at MMS (IQMAS-Jupyter-Example).
Do not forget to specify your privileged credentials at the top of the notebook, in the first code cell
Force the server to refresh its knowledge of commits in the repository:
iqs.mms_repository.update_mms_repository()
Index another model from the repository, and then load the index into server memory:
iqs.persistent_index.index_model_compartment(model)
iqs.in_memory_index.load_model_compartment(model)
iqs.integration.elastic_search_load_model_compartment(model)
model_in_rdf = schema.ModelCompartmentWithModelFormat(
model_compartment = model,
format = "RDF_TURTLE"
)
iqs.persistent_index.transform_model_compartment(model_in_rdf)
iqs.integration.aws_s3_publish_model_compartment(model_in_rdf)
iqs.integration.aws_neptune_load_model_compartment(model_in_rdf)
iqs.queries.unregister_all_queries()
analysis_config_name = "My first analysis configuration with IncQuery Model Analysis Suite"
for config in (
config
for config in iqs.analysis.list_model_analysis_configurations().model_analysis_configuration_identifiers
if config.configuration_name == analysis_config_name
):
iqs.analysis.delete_model_analysis_configuration(analysis_configuration_identifier = config)