OSGi Configuration Admin and MetaType Service - osgi

I've been using the OSGi Configuration Admin to implement some basic configuration capability in our program. I now started looking into the MetaType Service specification because I need type information for each configuration property.
It's unclear to me how these two services interact. The Configuration Admin deals with essentially untyped Key/Value pairs. The MetaType Service knows names and types (among other things) of configuration properties, but not their values. My goal is to dynamically generate a configuration/preferences dialog for all components which have a configuration and corresponding metatype information. According to the MetaType Service spec, the service was conceived to cover this exact use case. So I reckon it shouldn't be too difficult
I can retrieve the metatype information with the following the sample code:
ServiceReference metatypeRef = bundleContext.getServiceReference(MetaTypeService.class.getName());
MetaTypeService service = (MetaTypeService) bundleContext.getService(metatypeRef);
MetaTypeInformation information = service.getMetaTypeInformation(myBundle);
After retrieving the MetaTypeInformation object for the required bundle, I have access to all the information contained in the metatype XML definition. In particular, it is possible to access the ObjectClassDefinition:
ObjectClassDefinition ocd = information.getObjectClassDefinition(pid, null);
AttributeDefinition[] attributes = ocd.getAttributeDefinitions(ObjectClassDefinition.ALL);
My questions are:
Given the AttributeDefinition; how can I retrieve the actual value of the underlying property? I know its name, but not its value.
How can I enumerate the metatype information for all components in all bundles that are currently present (active and inactive)? I know how to list all configurations through the Configuration Admin interface. It there perhaps a way to get to the MetaTypeInformation from the Configuration?

The Configuration Admin and MetaType services are separate, but related, specifications. There is no hard link between them, which I think is probably one of the main points that will help to answer your questions.
Essentially Configuration Admin is a store of configuration records. Each configuration record has a unique persistent identifier (PID) and if the configuration record is for a factory configuration then it will also have a Factory PID. The configuration record then also contains a number of key value pairs, where the key is always a String, and the value is one of a limited set of types.
Metatype, on the other hand, is a tool for providing configuration definitions. These describe the expected layout of keys and values in a configuration, including things like the type of the value associated with a given key, a minimum/maximum size for the value, an enumerated list of allowable values, and potentially a default value. Each key/value definition is held in an Attribute Definition, and these are grouped together in an Object Class Definition, which is associated with a PID.
The important difference is that Metatype knows nothing about what the configuration actually is at runtime (it's just information about what shape the configuration should be). Similarly Configuration Admin knows nothing about what shape the configuration should be, it just knows what the values currently are.
Therefore:
Given the AttributeDefinition; how can I retrieve the actual value of the underlying property? I know its name, but not its value.
You need to identify the PID associated with the ObjectClassDefinition containing the Attribute Definition, and then to use this to find the relevant configuration dictionary in Configuration Admin. If the OCD is for a factory PID then you will need to identify which of the configurations for that factory PID you want to look at.
How can I enumerate the metatype information for all components in all bundles that are currently present (active and inactive)? I know how to list all configurations through the Configuration Admin interface. It there perhaps a way to get to the MetaTypeInformation from the Configuration?
The MetaTypeService is a service in the OSGi Service Registry that you can use to ask for the MetaTypeInformation for a given bundle. If you ask for the Metatype Information for each bundle in turn then you will have the information that you are looking for. There is no hard link between Configuration Admin and Metatype, so a Configuration object has no way of knowing whether a meta type exists for it.

Related

FileNet Change Document Class Security not updated

If a document of ClassA is changed to ClassB, security group of the document doesn't change i.e. it still has ClassA security group.
I'm trying to understand what could be the reason/benefit/advantage behind this?
I expected the security groups changed to Class but not.
In fact, the Documentation says exactly what you summarized in your question:
You can assign a different class to existing document objects. For
example, you might add a document and assign it a document class of
Manuals because you intend it to be a chapter in an installation
manual. Later, you find the document is better placed in your training
materials and change the document class to Courseware. Later still,
you decide to remove it from the manual and make it a Technical
Notice, which has its own document class of Tech NotesĀ®.
Assigning a different class does not:
Change the security permissions that the original document class directly applied to that document object. You can change the security
by editing the security lists of the document object.
Cause the content of existing document objects to be moved. The default storage area and storage policy of the new document class
apply only to new instances of the class.
You can also browse the existing versions of a document to examine the
history of the class assignments for the document. If your saved
searches use the former document class as a search parameter, you
might no longer find the document.
I think that the main reason has to be found in FileNet approach, that - being it an ECM and not a DBMS - sets a distinction between content and metadata. This brings some observations to my mind:
The ACL for a particular Document Class are defined in their Default Instance Security. As the name implies, these are the security rules set by default when an instance of that class is created. This does not mean that a strict bound between a Document Class and their ACL exists, just that a default setting exists.
Consider the example in the Documentation: a document has been reclassified from Manual to Courseware. This could mean that some operations have been done on that document, before the class' change. If those operations were done by users that have visibility on Manuals, but not on Courseware, it's not right to brutally hide that document to those users.
Generally speaking, separating the CHANGE_CLASS permission from others (as WRITE, DELETE, etc...) adds a bit of freedom to software designers and administrators that use FileNet. Considering the example above again, hiding the document (or changing the permissions), could be necessary in case of a transition like "Public Administration -> Top Secret", but it could not be the case of "Manuals > Courseware".

Nifi: Reading external properties in custom Processor

I have updated the variable registry to point to a custom properties file and i am able to read those in my processors using expression language with out any issues.
How ever i want to read them in my Custom Processor's (extending the AbstractProcessor) onTrigger()
I tried flowFile.getAttributes() and context.getAllProperties() and it is not getting picked up.
Appreciate any inputs.
Thanks
To clarify, you want to reference the value of these externally-defined variables inside the application logic of your CustomProcessor#onTrigger() method?
You can:
Load the variable definitions by querying NiFiProperties#getVariableRegistryProperties() or NiFiProperties#getVariableRegistryPropertiesPaths. Once you have a reference to the variable definitions, you can parse and use them as you wish.
You can reference them via the flowfile attributes or processor properties if those attributes or properties support Expression Language and it is appropriately scoped. The PropertyDescriptor will list expressionLanguageSupported() and return an ExpressionLanguageScope, which is an enum consisting of NONE, VARIABLE_REGISTRY, and FLOWFILE_ATTRIBUTES (which also includes the VR).
I don't understand the scenario where you want your code to load custom variables that aren't controllable by the flow administrator, which would be populated via processor properties or flowfile attributes. If you really feel you need to access custom variables that aren't available via the context or flowfile, you can use Option 1 above, but you could also theoretically store those variables in environment variables, System properties, etc.

Suggested way to prohibit certain attributes on create in Spring Data REST?

Spring Data REST has been working exceptionally well for me, but I need to be able to restrict what parameters the user may provide when creating certain resources. For instance, the user should not be able to dictate the ID assigned to the created resource or the activation state of an account, let's say.
My approach to this so far is simply to clear or reset these fields manually in a repository #HandleBeforeCreate event handler. Is there another, more clever option for restricting the accepted POST data for a resource?
Additionally, there are cases where a CRUD call needs to specify additional, contextual attributes that are not explicitly part of the target resource but may be used in the process of creating the resource. What is the appropriate way to handle this case?
You can define a custom validator by implementing org.springframework.validation.Validator and override validate(Object object, Errors errors) and validate the input fields and then populate or make necessary changes to the fields as required to the input request object.
You can refer here for more details and also here for an example.

How to get the name of the type of a ServiceReference?

I have a ServiceReference instance of which I want to get the name of the type it is registered as.
For example, the service may be a WordService, implemented by WordServiceImpl. I would like to retrieve "WordService". ServiceReference.toString() gives me something close to what I want ("[org.example.WordService]").
However, I'm assuming the toString() format isn't standard across runtimes. Also, I'd rather not inspect the interfaces of the implementing type to manually look for the interface, as I'd still have to randomly pick the right one in case of multiple interfaces.
Thanks in advance!
Silly, but I actually figured it out almost immediately after posting.
Retrieve the value of the objectClass property through the service reference:
String[] objectClass = (String[]) reference.getProperty("objectClass");
As you can see, this is an array of Strings. In my test cases, the first and only entry contained the provided service interface (org.example.WordService). I'm assuming multiple entries would appear if the implementation provides services through multiple interfaces.
I'm assuming this is standard OSGi...

Can multiple ProgIDs point to the same ClsID?

I am working on a set of what are essentially plugins, which are COM servers. Each plugin has a set of configuration data which is managed by another component, the primary key to the configuration data is the plug-in's ProgID. When the plugin needs to access a configuration item, it makes a call and passes in its ProgID and the name of the property required. This is a legacy design and I must maintain backward compatibility.
I now have a requirement to load multiple instances of each plugin, with each instance having a different set of configuration data. The solution I'm considering is to create multiple unique ProgIDs for each plugin, each ProgID would point to the single ClsId for the plugin. Thus, each instance of the plugin would be indentified by its ProgID, the ProgID is still used as the primary key for the configuration data and everything is 100% backward compatible.
So, the questions:
Is this an acceptable technique? (multiple ProgIDs all pointing to a single ClsID).
When my plugin loads, would it be able to tell which ProgID was used to create it?
Prog ids are typically used in two ways: to detect a class id corresponding to a prog id (CLSIDFromProgID() function) - this is used to later call CoCreateInstance() - and to detect a prog id for a given class id - this is usually used to display a human-friendly version of a class id.
Those mappings imply that there's a HKCR{ProgId}\CLSID key with a default value equal to the class id and a HKCR\CLSID{classid}\ProgID key with a default value equal to the ProgId, which means that the mapping is one-to-one. You will just not be able to have more than one prog id under one class id.
A COM component is loaded by calling CoCreateInstance() which is passed a class id - obtained by any means possible, using CLSIDFromProgID() included. There're no ways for a component to tell how the class id was obtained.

Resources