Category Archives: Week 9

Software Architecture

I was curious to learn more about software architecture and, based on the article “Software Intelligence for Digital Leaders” I understood what software architecture is. Much of what we do on a daily basis, from using a cell phone to clocking into sending an email depends on the software architecture of the systems that we use. Without software architecture, so much of what we know and use would not be possible, but what is it?

Software architecture is what makes it possible for innovation within an organization. It’s simply the organization of a system and this organization includes all components, how they interact with each other, the environment where they operate, and the principles used to design the software.

Software architecture is a blueprint for both the system and the project. It defines the work assignments that must be carried out by design and implementation teams. The architecture is the primary carrier of system qualities such as scalability, performance, modifiability, security, and cost reduction, none of which can be achieved without a unifying architectural vision.

Some benefits of Software Architecture

Software architecture is extremely important for a software project. Let’s see some benefits of software architecture that will tell us more about how it can help us in our project and why we should invest in good software architecture.

Identifies areas for potential cost savings. An architecture helps an organization to analyze its current IT and identify areas where changes could lead to cost savings.

It creates a solid foundation for the software project

Makes your platform scalable

Increases performance of the platform

Reduces costs, avoids codes duplicity

Implementing a vision. Looking at the architecture is an effective way to view the overall state of IT and to develop a vision of where the organization needs to or wants to go with its IT structure.

Better code maintainability. It is easier to maintain existing software, as the structure of the code is visible and known, so it’s easier to find bugs and anomalies.

Enables quicker changes in IT Systems. There is increased demand for systems to change quickly to meet rapidly evolving business needs, legislative requirements, etc.

Increases quality of the platform

Helps manage complexity

Makes the platform faster.

Higher adaptability. New technical features, such a different front ends, or adding a business rule engine is easier to achieve, as your software architecture creates a clear separation of concerns.

It helps in risk management. Helps to reduce risks and chances of failure.

Reduces its time to market, reduces development time.

Prioritize conflicting goals. It facilitates communication with stakeholders, contributing to a system that better fulfills their needs.

I talked about software architecture because as a computer science major interested in software, learning its importance is really vital and necessary. Software is important for creating projects and maintaining them, which is a huge responsibility.

To sum up, software architecture dictates technical standards, including software coding standings, tools, and platforms. It gives the right technical solutions to ensure your success.

What Is Software Architecture – Examples, Tools, & Design | CAST (castsoftware.com)

15 benefits of software architecture you should know (apiumhub.com)

From the blog CS@Worcester – Gracia's Blog (Computer Science Major) by gkitenge and used with permission of the author. All other rights reserved by the author.

REST API Security

Christian Shadis

For the past couple weeks, my Software Construction, Architecture, and Design course has been focusing on the anatomy of simple REST APIs. While we were learning about how to create endpoints to retrieve data from the backend, it was as simple as just extracting the data from the database on the backend. This seemed too basic to me. Though I was sure there was still plenty of unexplored detail in the backend regarding security protocols, I was curious to see how security measures can be implemented in a REST API like the ones we have been working with.

Chris Wood discussed Security Scheme Objects and their role in the REST API, listing supported security mechanisms (Basic Authentication, API Key, JWT Bearer, and OAuth2.0), in his 2019 article REST API Security Design. He began by defining what a REST API Security Scheme Object is: a Component object (like Schemas or Responses) which “[describes] the security requirements for a given operation.” There is not a specific object for each of the mechanisms listed above, but rather a single Security Scheme Object that can represent any of the four mechanisms. The Object is defined in the top-level index.yaml file under the Components section, the desired mechanism is applied, and any additional arguments specific to the mechanism are passed. Once it is defined, the Security Scheme Object can be applied to individual endpoints or operations. For example, for some path /users/, we define an operation get, and underneath the parameters and responses section, a security section can be added containing an array of Security Scheme Objects to be applied. If we define a BasicAuth object and assign it to the get /users/ endpoint, other developers know that the operation should have basic authentication.

My main takeaway from the article was that my perception of API security was flawed. Whereas I had considered the idea of implementing security measures directly into the API itself, the article outlines instead that security measures in an API consist primarily as a guide or a definition of security requirements for other developers to uphold. For example, authentication itself is not performed inside our REST API by implementing one of these Security Scheme Objects. Rather, the API designer can specify that some specified authentication should be included in certain operations by defining them in the API.

While security measures in API design may not be as essential as I believed, the article asserts that it is a vital factor of API design. As I continue my career as a developer, I plan to develop all my applications in the most secure way possible. Since API design is such a fundamental aspect of web application development, I am glad to have gained some exposure to how security measures are implemented.

Reference: https://blog.stoplight.io/rest-api-security

From the blog CS@Worcester – Christian Shadis' Blog by ctshadis and used with permission of the author. All other rights reserved by the author.

Query String

Let me just begin by saying I really like how this blog post was organized and written. It starts off very formally by giving definitions for the terminology that they would use throughout the post and then transitions to explain those same terms in layman terms. With the way the post is written, the author makes it so even a person without a Computer Science background can semi follow what is going on in the post because the author explains the concepts using things that everyone sees and uses on a day-by-day basis.

The post starts with an example of a web URL and how the statement after the web extension is actually a query string. Then the article goes on to talk about how you can format your search to look for a specific pattern, and max or minimum string length. After going over the basics of how to format query strings, they go to talk about how you can combine multiple criteria to further down your search.

For example:

Somedictonary.com/words/?letter=5&partOfSpeech=noun

This finds you all of the five-letter nouns in the dictionary.

The reason why I chose this particular blog post to read and talk about this week is because it is relevant to what we are learning in class. It is a topic we are going to go over in class and have already talked a little bit about this topic in class. In addition, we are using also using it this week for the homework. I chose this post because I think it does a great job explaining the topic. The post is short and worded in a way that I think is easy to understand. It also uses a lot of images and examples, so it was also easy to follow along with what the author was saying about the topic.

In class when we started talking about this topic, I did not think it was particularly difficult to understand, but another reason I chose this blog post is that I have always been the kind of person where I either “use or lose it”. I have always been the kind of person where whenever I learn something new, I need to apply that information or forget about it.

In class, I immediately made the connection that you can use query strings to refine searches in databases but after reading this blog post, I learned you can also apply it to websites. In a way, I think I have always known this because often times when I am navigating a website and want to go from one page to the next, I may just change the page number or page entry in the URL. I don’t think I would have put two and two together and realized on my own that what I was doing was modifying the query string or that I was switching from one endpoint to another.

From the blog CS@Worcester – Just a Guy Passing By by Eric Nguyen and used with permission of the author. All other rights reserved by the author.

Notes on “Notes on the Errors of TEX”

Having just read a short keynote address* by Donald Knuth from 1989 about the development of his typesetting system, TeX, I’m struck by how little the core methodology of computer programming has changed in the last thirty years.

Students and new programmers can struggle with the difference in scale between real-world applications and textbook examples. Knuth feels that his typesetting system, TeX, is a useful illustration to beginners because it is a “medium-size” project: small enough for one person to understand given a reasonable amount of effort, but large enough to draw meaningful architecture and design lessons from.

Here, he outlines a number of lessons he took from the process of writing TeX. There’s nine, and they are only discussed briefly here (this is a summary of a much larger paper he wrote, which is simply called “The Errors of TeX.” I think they’re generally all very good, but for the sake of brevity I’m only going to focus on one of them.

Knuth’s first lesson here, which I think is the most important, is that it is not enough to merely specify a design. The implementation isn’t just physically necessary to create the product, but the actual process of implementing it is where the most important information about the design comes from. This seems maybe so obvious that it’s not worth actually saying, but I think it’s important and easy to lose sight of. Looking back on it, I think that personally, my greatest stumbling block in programming is what I would call overdesign. I would sit down and construct a conceptually perfect model in my head, and then it would fall apart on me as I attempted to implement it without me really understanding why.

At the time, anyway. Looking back now, I have a pretty clear idea, and Knuth expresses a similar idea here. The problem is that I viewed implementation as an externality to the design process rather than as one of the most significant components of it. Fundamentally, the purpose of thinking about software architecture is to minimize difficulty in implementation, and so actually writing the code is the most important source of data in the process. For example, it’s one thing to know, vaguely, that Microsoft’s DirectSound library can provide audio playback functionality to an application. But knowing specifically that it needs a ring buffer and understanding all the small, tedious details in setting it up might push you in the direction of architecting your program a specific way, or using a different audio library if you’d rather not. Granted, I guess it’s possible that you might come to the same conclusions simply looking at the documentation, but my mind doesn’t work that way, and I suspect that experience is generally a better teacher.

*Knuth, Donald E. (1989). “Notes on the Errors of TeX” (PDF).

From the blog CS@Worcester – Tom's Blog by Thomas Clifford and used with permission of the author. All other rights reserved by the author.

Technical Debt/Cruft

Hello everyone,

https://dev.to/6figuredev/episode-207-tech-debt-vs-cruft

This podcast in particular talks about technical debt in detail, as well as how to handle it. It introduced me to a term I had never head before called Cruft. Cruft being not traditional technical debt but specifically a type of debt where the developer who wrote the code did not make the effort to make the code clean and or work well. I never made the distinction in my own mind as to consider the possibility that the lack of best practices or simply writing the code wrong could be considered as that type of technical debt.

Now I don’t mean the developer was malicious or perhaps lazy, while it could be considered a possibility it seems to be not a scenario that happens enough to be something that requires a term like that. I also like having that extra terminology as technical debt as a definition can be left to an intentional design choice that leads to the creation of technical debt that most times are made in consensus rather than specifically one user not knowing how to code it or that user writing poorly designed code.

Cruft also gives a more specific term for a business to focus more on as it has the greater debt value for the company when needing to rework your product. If the code is rushed and written poorly, when errors arise the pressure is greater on the development team and will lead to failure or delays.

With Cruft as the core of that perspective on technical debt, regular technical debt can be just the debt that was planned and agreed upon allowing you to release and work on it later.

This podcast also introduced me to another great term that is separate to legacy code. With legacy code it’s old enough that it doesn’t meet the definition of Code Rot. Code Rot isn’t keeping up with older code so old as to be legacy code, but code that hasn’t been touched in a while and isn’t kept up to date with the newer builds and similar code design.

From this podcast it gave me an interesting mindset when thinking about a production cycle and acknowledging technical debt as kind of being inevitable and something to try to plan before sprints as apart of the team and being prepared for it. Cruft is really what I thought technical debt to actually be, because I was only really reflecting on code being written by one person. I for some reason ignored the aspect of working on the development team and it has changed my idea of development. Cruft really is just a more personal or workspace issue. One being fighting against the urge to take the easy way out and the other being a pressure outside what I as a developer couldn’t control but rather a business forcing the cruft to occur by forcing shortened deadlines.

From the blog CS@Worcester – A Boolean Not An Or by Julion DeVincentis and used with permission of the author. All other rights reserved by the author.

Software Construction Log #5 – Understanding Port Mapping in Docker

          In a previous post regarding containerization, I briefly mentioned the uses of containers regarding application development and deployment prior to specifically learning how to utilize Docker and its containers. I went on to explain how Docker can handle development of applications through the use of images that contain the dependencies needed to be used for development, as well as how Docker also manages data retention between the local host system and the container file system through the use of volumes and mount binds. My learning of Docker started with a focus on local application development and deployment before moving onto utilizing ports to access the running applications through the network via a port number.

          By default, ports in a Docker container are not published and thus cannot be accessed this way, even if the container itself is up and running. This means that if one needs to access an application from port 5000 of the local host, this would not be possible given that such port may have not been published in the first place. Therefore, an important part for deploying web-based applications through docker involves utilizing the container’s ports. Such concept is referred to as “port mapping”, in which case ports of the localhost are mapped to specific ports in the container. This is a useful concept in the case that, during development, multiple containers that are running may need to use the same ports, therefore different ports of the localhost are mapped to that specific port that needs to be used and directing traffic appropriately, thus avoiding any potential port conflicts between containers.

          As I was researching for resources specifically talking about port mapping and port forwarding on Docker containers, I came across the following article named Understanding Docker Port Mapping to Bind Container Ports on LearnItGuide.Net. In this article, the author goes through the process of explaining how to map docker ports by demonstrating how the process is done through the command line by using a basic application and multiple containers as an example. Moreover, they show the multiple ways a port value can be expressed, which ways include either passing the port number directly (thus needing to access the application through localhost:port_number), by passing the IP of the host along with the specified port number that needs to be mapped, or by using automapping and thus mapping a random host port to the docker container. However, it is important to note that port mapping can also be applied using docker-compose YAML files. In an article named Understanding Docker Port Mappings on Dev-Diaries.Com, the author explains how port mapping works when using docker-compose files while showing examples of the ways we can map host ports to docker ports.

          Although there is more to port handling, such as exposing ports to only be accessible to linked services, it is still important to know how ports work in Docker containers in order to properly utilize them in the process of development and deployment.

Direct links to the resources referenced in the post: https://www.learnitguide.net/2018/09/understanding-docker-port-mapping.html and

Recommended materials/resources reviewed related to Docker port publishing:
1) https://www.dev-diaries.com/social-posts/docker-port-mappings/
2) https://betterprogramming.pub/how-does-docker-port-binding-work-b089f23ca4c8
3) https://www.tutorialspoint.com/docker/docker_managing_ports.htm
4) https://www.ctl.io/developers/blog/post/docker-networking-rules
5) https://nickjanetakis.com/blog/docker-tip-59-difference-between-exposing-and-publishing-ports
6) https://riptutorial.com/docker/example/2266/binding-a-container-port-to-the-host
7) https://www.dev-diaries.com/social-posts/docker-port-mappings/
8) https://www.whitesourcesoftware.com/free-developer-tools/blog/docker-expose-port/
9) https://digitalthoughtdisruption.com/2020/09/28/docker-port-mappings/

From the blog CS@Worcester – CompSci Log by sohoda and used with permission of the author. All other rights reserved by the author.

Semantic Versioning

Semantic versioning is a versioning scheme in three parts; major.minor.patch. Patch is incremented with the addition of a bug fix, minor is incremented with the addition of a new feature, and major is incremented when the changes being made are incompatible with previous versions. Though it is among the most popular versioning schemes, Colin Eberhardt explains in a blog post “Semantic Versioning is not Enough” that it is not without issue.

Eberhardt describes that issues may surface when updating the dependencies of a project. There are two ways to update a dependency within a project; passively or actively. Passively updating allows a computer to update the dependency without human intervention while actively updating requires a human to manually update the dependency.

When adding a library to your project, you may specify a range of acceptable versions of that library. This hands the decision of whether to update a dependency to a new version, provided that the new version is still within range. Eberhardt warns that declaring dependencies like this could create different development environments on different machines, where one machine decides that an update is appropriate and another does not. Applications may function differently after even small bug fixes in their dependencies. In addition, passively updating to a version of a library with new features is nearly pointless. You would need to change your code to be able to use those features.

It seems more useful to actively accept updates to a dependency. This is fine for patch updates since these do not require any alterations to your code. However, updating to either a minor or major update would require you to change your code, whether it be to utilize a new feature or to prevent your project from breaking. Eberhardt argues that, because of this, the distinction between a major and a minor update is not useful.

Eberhardt also points out that a major update can often fail to convey the severity of what was changed. A trivial breaking change would increment the same as a rewrite of an entire library. Eberhardt suggests combining romantic and semantic versioning by giving names to more significant changes.

I selected this article because I thought it would be useful to see another perspective. Eberhardt seems to have a lot of experience, and he draws from that experience to write this critique. I still think that semantic versioning is a useful scheme, but it is interesting to see a critique of something so popular. I think the suggestion of naming significant updates in addition to incrementing the major number is a useful one that I will try adopting in future projects.

From the blog CS@Worcester – Ciampa's Computer Science Blog by graceciampa and used with permission of the author. All other rights reserved by the author.

Git Gud Skrub

So I’m going to have to be honest with my readers, and also I’m going out on a limb here: I am not the most experienced with Git. This is especially detrimental when I am taking a course that requires regular usage of Git, and that course is a limited time offer. What am I going to do? In my general theme of learning, I am going to practice over and over again until I finally “git gud” (as the kids would say) at Git.

Git is a version control software used to create different “branches” of a project. These branches can be local or remote; they also can “pull” information from other branches, and “push” or “merge” this information back as well. Other important controls include: rebasing, location arguments (such as HEAD) and “status-checking”. These commands, and many more, are used to ensure that software can be created or polished in separate branches while the “main” branch is still operational. When the changes are tested and ready to be added to the program, they can be “merged” back in.

As a way of “branching off” from my traditional form of blogs, I have decided to link a unique source. Instead of an article or a YouTube video, I have linked an interactive tutorial called “Git-It”. This is because I believe that the best way to learn Git is by practicing it over-and-over; similar to a “traditional” programming language, hands-on experience with Git will take a programmer further than any abstract knowledge will. In a nutshell, this tutorial will teach you all the basics needed to understand Git. These basics include, but are not limited to:

  1. Creating, modifying and deleting repositories
  2. Pulling and Pushing data from other repositories (both local and remote)
  3. How to clone material from a remote repository to a local computer
  4. Creating and merging branches

Not only is Git going to be essential for completing homework assignments, but it is practically unavoidable in the software workforce. Similar to Singleton/Strategy refactoring, Git allows for different branches to create different implementations, while all still referring to one “global, main” branch. Branches can also be used for various SemVer levels in a project; should changes need to be made, progressing or regressing a project (through committing or reverting, respectively) can be done.

Most importantly, I feel as though Git is a great tool to help me understand the concept of continuous integration. As mentioned before, Git allows for multiple branches of software; these branches can then be “forked” or “cloned” to private servers or local computers. This gives the programmer a copy of the project to work on, while the actual project is still running for its customers. This “language” combined with Docker containers, emphasizes the class theme of being able to work with software on different platforms, thus maximizing versatility.

Link: http://jlord.us/git-it/challenges/get_git.html

From the blog CS@Worcester – mpekim.code by Mike Morley (mpekim) and used with permission of the author. All other rights reserved by the author.

InfoSeCon 2021

Dr. Cunningham focuses on integrating security into operations; leveraging advanced security solutions; empowering operations through artificial intelligence and machine learning; and planning for future growth within secure systems.

https://www.youtube.com/watch?v=VBfTpmEyHy0

This video is the Keynote speaker’s presentation for the Raleigh chapter of the Information Systems Security Association for their 2021 fundraising event called InfoSeCon. I used to be a chapter member before I moved here to Massachusetts and I try to keep up with some of their announcements and events from time to time.

Dr. Cunningham was a previous Keynote speaker and to see him return this week on their Youtube channel was exciting. He’s known for being the creator of the Zero Trust eXtended (ZTX) framework which is a framework of network security protocols that prioritize network isolation and continuous monitoring and validation.

This keynote presentation primarily focuses on network security and serves as a reminder of best practices for operating a corporate network while utilizing a zero-trust framework. He uses horror movies as a theme to tie everything together and make it engaging for his audience and I really appreciate the consideration. InfoSeCon took place back in October so it was topical and showed that it wasn’t some canned presentation that he had been giving all year. It really goes to show that one of the largest hurdles to Network Security is just communicating the importance of simple practices and getting your audience, whether it be clients that hire you on to improve their company’s practices or systems or if they’re users already in your network to follow them.

That’s really one of the main appeals of a Zero-Trust framework. Traditionally, network security is treated as an Us vs Them scenario where it’s always something that is being inflicted upon the company rather than the natural conclusions of risky behaviors. ZTX operates differently; it assumes that you can’t trust the end users to know everything you know about what they should or should not do. It encourages the security professionals to segment everything and isolate as much as possible so that when one person unknowingly invites the vampire into the house, we can shut another door in its face and not have to worry about evacuating everybody.

Specifically, he stresses the importance of maintenance within your systems so that older vulnerabilities aren’t taken advantage of and make life harder in the future, to listen to your users, that moving to the cloud is likely the best solution for people dealing with a “haunted” infrastructure, as well as a lot of other really great advice.

While a lot of the best practices are simple and seem like common sense, I always appreciate a reminder so that I don’t make bone-headed mistakes that can cost either me or my employer great sums of money. It’s important as I learn more and more about Software design and architecture that I keep in mind how I could be unknowingly creating vulnerabilities that could be exploited if ever someone decided to try hard enough to find them.

From the blog CS@Worcester – Jeremy Studley's CS Blog by jstudley95 and used with permission of the author. All other rights reserved by the author.

Microservices Architecture: Uses and Limitations

Using information found by Narcisa Zysman and Claudia Söhlemann we take a closer look at microservices architecture and learn about why it is being widely used and what are its limitations.

Uses:

Better fault isolation: If one microservice fails, others will likely continue to work.

Optimized scaling decisions: Scaling decisions can be made at a more granular level, allowing more efficient system optimization and organization.

Localized complexity: Owners of a service need to understand the complexity of only what is within their service, not the whole system.

Increased business agility: Failure of a microservice affects only that service not the whole application so enterprises can afford to experiment with new processes, algorithms, and business logic.

Increased developer productivity: It’s easier to understand a small, isolated piece of functionality than an entire monolithic application.

Better alignment of developers with business users: Microservice architectures are organized around business capabilities, developers can more easily understand the user perspective and create microservices that are better aligned with the business.

Future-proofed applications: Microservice architectures makes it easier to replace or upgrade the individual services without impacting the whole application.

Smaller and more agile development teams: Teams involve fewer people, and they’re more focused on the part of microservices they work on.

Limitations:

Can be complex: While individual microservices may be easier to understand and manage, the application may have significantly more components involved, which have more interconnections. These interdependencies increase the application’s overall complexity.

Requires careful planning: Because all the microservices in an application must work together, developers and software architects must carefully plan out how to break down all the functionality and dependencies. There can be data challenges when starting an application from scratch or modifying a legacy monolithic application. Also, multiple iterations can be required until it works.

Proper sizing is critical and difficult: If microservices are too big, might have all the drawbacks of monoliths. If it is too small, the complexity of the individual services is moved into the dependency maps, which makes the application harder to understand and manage at scale.

Third-party microservices: Third-party services can change their APIs (or dependencies) at any time and in ways that may break your application.

Downstream dependencies: The application must be able to survive failures of individual microservices, yet downstream problems often happen. Building fault-tolerance into an application built with microservices can be more complex than in a monolithic system.

Security Risks: Microservices growth in popularity, may increase an applications’ vulnerability to hackers and cybercriminals. Because microservice architectures allows the use of multiple operating systems and languages when building an application, there’s the possibility of having more targets for malicious intrusions. We are also unaware of the vulnerabilities of third-party services being used.

When complexity increases, we make sure it is warranted and well understood. Regularly examining interconnected set of microservices so the application does not crash. Learning about limitations helps us come up with such solutions which we can apply in our future work and when we work on LibreFoodPantry system.

Source:

https://www.castsoftware.com/blog/microservices-architecture-a-good-or-bad-approach

https://kruschecompany.com/microservice-architecture-for-future-ready-products/#Microservices_cons

From the blog CS@worcester – Towards Tech by murtazan and used with permission of the author. All other rights reserved by the author.