Split up Metadata Interface for backend

Hi @stefan.feilmeier I wanted suggest an architectural change in your Metadata Backend interface
io.openems.backend.common.metadata.Metadata

Currently this interfaces combines Metadata for User and for Edge in a single interface. This prevents me from implementing an alternative User-Backend while still keeping Edge-Information in a file or elsewhere.

This could work out since it’s only the users that need to know about Edges.

Hi Simon,

yes, that sounds absolutely feasible. Metadata just somehow evolved from how we use it in the Odoo backend:

I know that opernikus was doing some development for integrating with Keycloak. @c.lehne: any ideas or remarks about this approach?

https://www.keycloak.org/

Regards,
Stefan

Hi Simon,

as @stefan.feilmeier remarks we are working on a keycloak integration. We are reworking the bundle right now, because we also want to use the postgresql functionality of the odoo bundle. Thats why the bundle is not yet published.
You are right, the Metadata interface is a bit unclean from an architectural point of view. That in mind, we have already separated our bundle implementation into

EdgeHandler
  public abstract Optional<String> getEdgeIdForApikey(String apikey);
  public abstract Optional<Edge> getEdge(String edgeId);
  public default Edge getEdgeOrError(String edgeId);
  public abstract Optional<Edge> getEdgeBySetupPassword(String setupPassword);
  public abstract Collection<Edge> getAllEdges();

and

UserHandler
   public User authenticate(String username, String password);
   public MyUser authenticate(String token);
   public void logout(User user);
   public Optional<User> getUser(String userId);
   public void addEdgeToUser(User user, Edge edge);
   public void updateUserLanguage(User user, Language language);
   public Map<String, Object> getUserInformation(User user);
   public void setUserInformation(User user, JsonObject jsonObject);
   public byte[] getSetupProtocol(User user, int setupProtocolId);
   public int submitSetupProtocol(User user, JsonObject jsonObject);
   public void registerUser(JsonObject jsonObject);

This separation might be a good starting point for a separation of the Metadata interface also.
One could extract the edge methods from the Metadata interface, put them in a MetadataEdge interface
and modify

Metadata
    public MetadataEdge getMetadataEdge();
    ...

I am a bit unsure of the implications this might have!
For example, how do we use metadata.file for Edge handling and metadata.<mynewuserbundle> for user handling and how do we use them together?

Regards, Chris

1 Like

Hi @c.lehne ,

that new interface design would make integration of authentication service providers a lot easier.

If you plan to avoid any implications on other services you could create a proxy service:

Metadataservice implements Metadata
@Reference
protected volatile UserHandler userHandler;
@Reference
protected volatile EdgeHandler edgeHandler;

This would ensure EdgeWebsocket and others that bind Metadata will not be affected.

Best regards!