Clean Architecture / Hexagonal I/O adapters how to devide them - clean-architecture

In many articles I read about Clean or Hexagonal Architecture and I found there informations about I/O Adapters but still in many projects i have found repository with save / get method as a one class, one adapter with one implemented port.
Why isn't that in two different ports?
For example:
interface ProductOutput → with get methods
interface ProductImput → with save methods

Input Adapters are systems which can drive your "Hexagone" like IHMs, batches.
Output Adapters are systems driven by your "Hexagone" like databases, messaging systems.

Related

How can Clean Architecture's interface adapters adapt interfaces if they cannot know the details of the infrastructure they are adapting?

From what I've understood from Clean Architecture, every layer can directly depend only on internal layers and, related to external layers, only abstractions are allowed to be set as a dependency, with DIP. Following this rule, the Adapters layer is allowed to directly depend on the Application layer and it only can have the Infrastructure layer as a dependency through abstractions. In my conception, that does not make any sense because, in order for an adapter to be able to perform translation between interfaces, it must know in detail which interfaces it is adapting - not knowing details of one side, abstractions on the other side. I've searched for that and didn't find convincing answers.
This question is probably one of the most controversial in Clean Architecture and (as to my understanding) the one where Hexagonal Architecture and Clean Architecture differ the most.
The general concept in Clean Architecture is: the inner layer provides an interface which is implemented by the outer layer. This approach can be followed by the adapters layer as well.
Imagine you want to implement a repository pattern which accesses an SQL database. Then, in the adapters layer you would implement an interface from the use cases layer which is most convenient for the use cases. This interface would probably have APIs rather specific to the needs of the use cases like "GetAllCustomersWithOpenOrders" or "GetOrderHistoryOfCustomer". Now in order to implement these APIs the adapter would need access to the SQL database For that it would again define an interface which is convenient for the adapter, so it would probably define generic CRUD Apis to pass some SQL as string. This interface would then be implemented in the "frameworks and drivers" layer by a class which would then know how to access the database (it would have the connection string and may depend on a vendor specific DB access library).
With this approach the dependency rule of the Clean Architecture is maintained but it would probably raise 2 questions:
Isn't the adapter still "technology dependent" if it builds up SQL strings? Yes it is, but the adapter not necessarily needs to be technology independent, if it is independent from specific frameworks, vendors or external services. We could easily add another adapter which "creates a bridge" between the interface defined in the use cases layer and a document database.
What is the value of such an adapter if we need still one more interface and one more implementation in the frameworks layer? The answer probably heavily depends on the "conceptual difference" between those two interfaces. In the example above the adapter would still contain all the knowledge about the DB schema, how to do the joins and so how to build complex queries. The implementation in the frameworks layer would be very small as it would probably just pass on the SQL query through the vendor specific library to the proper DB instance. Replacing on DB vendor by another would be possible with minimal impact to your application. In other cases the ration might be the other way round and the adapter might only be a "data conversion" layer.
Personally I still didn't found a "silver bullet" to this question so I try to make a "pragmatic" decision, case by case, as I tried to summarize in my blog post: http://www.plainionist.net/Implementing-Clean-Architecture-Frameworks/
Update 2022-11-08
Created a YouTube video which discusses this topic in further depth: Repository Pattern: CORRECT vs. pragmatic? | Clean Architecture

Dependency between adapters in hexagonal architecture Spring Boot

I've been trying to refactor a brand new project to follow the hexagonal architecture and ddd patterns.
This is the structure of my domain. I have files and customer data. Entity wise this makes sense to be separated. The "facade" objects connect the ports with the domain. Quick example:
Controller (application layer) --uses--> Facade --uses--> Ports <--implement-- Adapters (infrastructure layer)
The problem I have is I have a third adapter (not in the picture) that is an external OCR app. It's an external client (we use a feign client to connect their API) and it provides customer data (first adapter), but also serves us with the raw data of images (second adapter).
My first two adapters have entities, repos and databases on our local systems but, this third one, to me makes sense given the theory behind hexagonal architecture, to be separated in its own adapter.
But then how do I use it from my other two adapters? Should the three of them be in the same adapter since they depend on each other? CustomerData and File have a One To Many relationship as well so maybe it makes sense?
I have only implemented the File part so far and have yet to refactor the CustomerData part since I'm trying to wrap my head around the concepts first.
I've seen a lot of articles but most of them are really simple with no real world examples and they have clearly separated domains.
Thanks a lot for the clarification in advance.
In lack of a better idea, since the interface ports are beans implemented by the facades, I'm wiring the ports I need in the other domain's facades and using them the same way as if it was a controller of that same domain. The diagram would be something similar to:
Facade (domain1) --uses--> Port (of domain2) <--implement-- Adapters (infrastructure layer)
Edit:
I've found out a very extensive article that is very useful to understand hexagonal architecture but goes even deeper.
Long story short, I'll copy the relevant part:
Triggering logic in other components
When one of our components (component B) needs to do something whenever something else happens in another component (component A), we can not simply make a direct call from component A to a class/method in component B because A would then be coupled to B.
However we can make A use an event dispatcher to dispatch an application event that will be delivered to any component listening to it, including B, and the event listener in B will trigger the desired action. This means that component A will depend on an event dispatcher, but it will be decoupled from B.
Hexagonal Architecture doesn't forbid the relationships between adapters.
Anyway, usually we will have a port for each external actor interacting with our business logic, and an adapter to translate to/from the actor.
You can take a look at this:
https://jmgarridopaz.github.io/content/hexagonalarchitecture-ig/chapter1.html

SNMP in context of SDN

SNMP is generally used to monitor the health of components in network.
For SDN [Software Defined network], is it desirable to use SNMP . I am having doubt like is it better to use some other protocol like NETCONFIG
In general SNMP can be used for configuration of a device, however personally I will not stretch it too far specifically when network configuration operation potentially spans across multiple devices and as a result will have higher order transaction requirements.
RFC3512 provides good perspective around configuration using SNMP. Reading through the RFC it will become apparent that within a device transaction relies on how well the MIBs (the objects used via SNMP for performing configuration changes) are designed and implemented. For configuration spanning across multiple devices the device transaction alone will not suffice, if rolling back the configuration is a requirement (this depending on the nature of service/use-case being addressed by your SDN controller). I would recommend reading the Transaction Control in MIB Objects further to understand the requirements on the protocol and eventually the capabilities of the MIB modules that one will be using for configuration.
Netconf was created with configuration of devices in mind and it offers various capabilities that are of use in this regard. These are covered in detail in the IETF standard for Netconf Protocol RFC under Capabilities section. The capabilities such as Candidate Configuration, Validate Configuration, Confirmed Commit, Rollback on Error and other such are specified in the standard which shall further aid in orchestration of a transaction across multiple device.

What exactly is Software-Defined Networking (SDN)?

I was poring over the docs for Open DayLight, and can't seem to wrap my head around what software-defined networking even is. All the media hype, blogs and articles I can find on SDN are riddled with buzzwords that don't mean anything to me as an engineer. So I ask: What (exactly) is SDN? What are some specific uses cases/problems it solves? Is it:
Just making proprietary networking hardware serve network APIs, thus allowing programs to configure them (instead of IT guys using a console or web interface)?; or
Implementing (traditionally proprietary) networking hardware as software; or
Writing software that somehow integrates with virtual networking hardware used by virtualization platforms (vLANs, vSwitches, etc.)?; or
Something else completely?!?
BONUS: How does Open DayLight fit into this equation here?
First of all, you are right, there is not official definition from NIST or some similar standardization body and the fact that its meaning is fuzzy is exploited by marketing people.
The main point of SDN is that it allows to program network functions with APIs.
In the past, networking devices like switches and routers were only configurable using a proprietary interface (be it vendor specific tools or just the CLI on the device) and there were no APIs which allow to configure OSI L2 - L3 aspects like VLANs and routes but also L6 - L7 aspects like load balancing highly dynamically. Btw. In the case of L6 - L7 functions, the term NVF = Network Virtualized Function seems to be established by now.
This is needed especially for multi tenancy capable virtualized IaaS systems. You can create new VPCs and arrange them together at will. To really isolate tenants from each other, you need to have a L2 isolation and so the same dynamics that is offered for VPCs is propagated to the networking for interconnecting them.
Conclusion: It is about your first bullet with the extension, that the APIs must not necessarily be offered by some hardware appliance, it can also be offered by some pure software implementation.
Regarding OpenDaylight:
It is the OpenStack pendant for SDN. They also actively push integration with OpenStack. They say they are an "open, reference framework for programmability and control through an open source SDN and NFV solution". This means it provides (as you say) a façade for the manfold aspects of networking.
They have all the big names as members which probably means they have the power to establish a de-facto standard like OpenStack did. Members benefit in that they can provide plugins, integrations and adaptations for their products so that they seamlessly integrate with OpenDayligh and you only need to care about a single standard API.
SDN is programmable networks. Different SDN solutions provide different functions in their APIs towards the app developer.
There is a good overview of SDN for software developers here:
https://github.com/BRCDcomm/BVC/wiki/SDN-applications
The most common elements for SDN solutions are
North-bound API: A programming interface used by an application/script to monitor, manage and control the network topology and packet flows within the network.
Network elements: Switching or routing network elements that enforce the rules provided by the application via the north-bound API. These elements may be physical (Cisco, Brocade, Tallac, etc) or virtual (Open VSwitch, Brocade Vyatta vrouter, Cisco 1000, etc) or a combination.
Controller-based solutions have a clustered architectural element (the 'controller') that provides the north-bound api towards applications and an extensible set of south-bound APIs to which network devices connect. Some controllers available today are OpenDaylight, Open Network Operating System (ONOS), Juniper Open Contrail, Brocade Vyatta Controller (ODL distribution), HP VAN Controller and more.
Best rules of thumb to understand an SDN offering:
Read its north-bound API - this tells you what you will be able to monitor, manage and control in your network.
Find out which south-bound APIs it supports - this tells you which switches/routers it might work with.
Some SDN use cases/applications:
DevOps/Admin automation - Applications and scripts that make a network admin or DevOps life easier through automation. OpenStack Neutron is a common example.
Security - HP provides 'Network Protector' that learns the topology of the network and then monitors activity providing alerts and/or remediation of non-compliant behaviors.
Network optimization
Brocade offers 'Traffic Manager' that monitors network utilization and modifies traffic flows in real time to optimize quality based on defined policies.
HP provides 'HP Network Optimizer' that provides an end-to-end voice optimized path for enterprise Microsoft Lync users.
Lyatiss provisions AWS networks in realtime to meet application needs.
Monitoring classroom time-on-task - Elbrys provides an application that provides a teacher with a dashboard to monitor student's time-on-task in real time and cause redirects of individual students to web pages of their choosing. (Disclaimer: I work for Elbrys Networks)
OpenDaylight project proposals page - https://wiki.opendaylight.org/view/Project_Proposals:Main
The concept of SDN is very simple. SDN decouples control-plane (i.e. decision making) from data-plane (the actual forwarding actions) and provides API between them (e.g. OpenFlow API).
Image source: https://www.commsbusiness.co.uk/features/software-defined-networking-sdn-explained/
With SDN architecture, network engineers no longer have to learn proprietary CLI commands for different vendors. They can focus on developing logically centralized control programs to make network global decisions and send it down to network switches (data-plane). Dumped network switches (data-plane) received controller rules/decisions and process network packets accordingly if no decision found they ask the controller.
For example: In SDN architecture routing algorithms developed as a program in the controller, it collects all required metadata (e.g. switches, ports, host connections, links, speed, etc) from the network then make a routing decision for each switch in the network. While in a conventional network, a routing algorithm is implemented in a distributed fashion in all switches (i.e. generally each switch has its own intelligence and makes its own routing decision).
SDN explained by Nick Feamster
Here is a good paper that illustrates the road map to SDN

can I develop a publish subscribe system without using MOM

I am trying to develop a publish/subscribe system.
To this end, I have read some papers and articles regarding it.
And they all talk about Messaging service as an integral part of publish/subscribe system.
My question is, can I develop a publish subscribe system without using MOM like JMS?
Or am I missing or oversimplifying things?
I do not think you are oversimplifying things. There are stand-alone products available that provide advanced functionality based on publish/subscribe, without being part of a larger MOM system.
One of them is a group of products implementing the Data Distribution Service (DDS) specification, as standardized by the Object Management Group (OMG). Check out this Wikipedia entry for a very brief introduction and list of references.
DDS supports many advanced data management features like a strong-typed and content aware databus, distributed state management and historical data access. Its rich set of Quality of Service settings allows to off-load a lot of the complexity from your applications to the middleware. This is all based on the publish/subscribe paradigm.
If you would tell more about your application, then I might be able to point you to similar use cases using this technology -- if you are interested.
It depends what you mean by "MOM". If you think MOM = JMS then yes, there are plenty of pub/sub applications which are not JMS servers (off the top of my head): 0MQ, TIBCO Rendezvous and the many AMQP implementations around.
I guess my definition of MOM is an infrastructure for reliably getting a message from one system to another in an asynchronous manner. Pub/sub is a feature on top of the message transport which allows a message to be distributed to multiple other systems. Once you get beyond the point of opening a socket and stuffing a bunch of bytes down it, I would argue you are in the realm of MOM.
So, no you don't need JMS to do pub/sub....there are plenty of open-source and closed-source alternatives out there. Which one depends on your requirements and skills.
You can look at multicast that provides one to many communication. Multicast does not require MOM, instead it requires multicast enabled IP network. Usually the network routers take care of creating copies of message and delivering messages to destinations.

Resources