
Senior Software Developer
SigmaSolveSenior Software Developer
Pearl TechnologiesSenior Software Developer
UpworkSenior Software Developer
ProAcumenTeam Leader
BexCode ServicesProject Manager
SigmaSolveSenior Software Developer
Freemind TechnologiesSoftware Developer
SigmaSolve IT Tech
Git

SVN

VSS

Azure App Services

Azure Storage

Azure Service Bus

Azure Event Hub

Azure Data Factory

Azure Functions

Apache Kafka

Stripe

PayPal

Twilio

SendGrid

MailChimp


CSS

CSS3

BootStrap

jQuery

HighCharts
.png)
Docker

PowerBI

PowerAutomate

NodeJS

SQL Server

MySQL

Entity Framework
Excellent work from Mit, highly recommended. His quality of work is phenomenal, understood from the very first communication the project and delivered a solution better than what we planned. We'll be doing more work together in the near future Mit. God speed.
Mit is reliable and we will continue to work with him.
Oh, hello there. Hello. My name is Mick Johan. I have 12 years of experience in Microsoft.NET-related technologies. That includes.NET Core, SQL Server, and the Microsoft Stack. Along with that, I have brief experience in Node.js as well. On the front-end side, I have good experience in Angular.js and Angular. I'm good with JavaScript, jQuery, and Bootstrap, so the entire front-end. For the last 3 and a half years, I've been mostly working in microservices and web APIs. The domains I worked in are pharma, logistics, and ecommerce. I did a lot of work in logistics. I also worked in ecommerce. These are the major areas of my background. For the last 5 years, I've been working remotely. So I have a lot of experience in remote working directly with clients. I've also worked as a dedicated developer for multiple clients, for example, C.H. Robinson. Apart from that, I have very good knowledge in low-code tools, including Jitterbit and SSIS. I worked a lot on integration work and ETL jobs in SSIS and Jitterbit. These are some of my capabilities. I've worked in Azure lately, including Azure Functions, Azure Message Queue, and I also happened to work on RabbitMQ. Currently, I'm working on Apache Kafka to exchange communication between microservices. So that is my technical background, and that's what I bring to the floor if I'm hired.
So, how I did last time, you know, it was not.NET 6. I think, it was.NET 3 for 1. So we on Azure, we were using deployment slots. So what we were doing is, you know, one deployment slot, you know. We targeted one deployment slot that is not inactive, that is active, and we'd deploy everything on that. That deployment slot was connected with the URL on which, you know, we would do UAT testing. We would test everything, and we had a very good understanding of a logical and study of what a test user are. So it wouldn't affect a lot on the actual live database. We would do all the parameter tests that had been given. We'd do a few manual tests. If there was any UI involved, we would do UI testing. And once that was done, we'd swap the deployment slot. So, you know, your deployment slot in which the latest code had been pushed from master, is now inactive. Right? But we test it on everything. You know, it's not a front end yet. Once we swap it, the latest master branch code becomes live, and the previous live deployment slot is swapped to inactive one, so it doesn't serve on the production, and that becomes your older version of it. So that's how we did. Apart from that, you know, there's a very good example of using a Kubernetes port, so you can have a priority or the default port. Right? So you can actually rotate those ports to make one as a primary or the default port. And that would make AKS a powerful tool to have near to zero time downtime. But, you know, there's a caveat. You know, if you're using caching, you have to ensure whenever these actions are happening, you clear your cache or the user sees the fresher website, because we experienced an issue using this approach. So at times, we were using the Redis caching, and the caching was still the same. So, you know, older users used to see a lot of older information, which was not relevant in the updated context. So what we used to do is, you know, we would clear the cache for that user. So the entire cache is cleared for that particular user, all the experiences, all the feature products, etcetera that had been cached, and they'd re-cache it. So, you know, the entire experience is new, but just that you don't see the downtime.
Will use to manage data mesh schema migration dot net application. Need to support multiple database providers. Okay. So I think let me tell you what we have done. It's currently for a logistics partner that we are using, we are migrating from one database under SQL Server. We are trying to migrate from to MongoDB. How we have done is, you know, we have created I providers. Now that I provider can have multiple instances. They are not singleton. So, you know, you can at any point, you can switch the database and it will start serving different things, and that's what we have been testing very rigorously about. Then this context will work as a singleton entity of the database connection, and that interaction gives me entities, you know, that are generic across the system. Right? And that using that, what we are doing is, you know, the entity stays the same, but, you know, the queries, the mediator says yields me something different. Right? So using that approach, we are using multiple data database providers, you know. I have worked in OpCommerce earlier, so OpCommerce is one of the e-commerce systems at this moment, you know, very popular in dot net. So in that also, they have created a similar way. The only thing is that in the case of OpCommerce, the database context is singleton. You cannot use multiple database contexts, in that one. But I would suggest, you know, always have multiple providers, you know, interfacing the abstraction and the underlying results should stay the same. So, you know, you can without damaging the architecture or, you know, you have injecting bugs, you can simply implement your database migration or a different strategy on different databases. It is easier. I'd like to share an experience earlier that, you know, at times, we used two database contexts, you know, the DB context in one of the applications, and we are just switching the connection, and we had a lot of issues back then. So, ideally, it should be handled by using a fair bit of abstraction to achieve what you need. But the underlying, you know, the DB schema or the DB operations, the DB services that we use to get the persisted data from back and forth. Right? They should stay the same and uniform. So, you know, you can achieve a better solution.
So, middle components are important because they work on the pipeline. So, in order to make them reusable, we have to use a lot of generic code for that. Right? A generic, and so I'll tell you an example of the current project that I'm working on. You know, we have coded about 5 generic, middleware-based services that entertain the middleware, and we have put that into a Nougat package. And we have microservices. There are 6 microservices in picture at this moment. You know, they have truck, we have carrier, we have service, we have trip, we have customer, and we have transportation. Sorry, the transportation. All of the services use the same middleware. Now, what those middleware do is to ensure that, first of all, your retail is serialized uniformly. So, the applications that use them, which are front-end applications that consume those microservices, if they need to contact another microservice, they can expect a similar result. That is one thing. Second, when we code the middleware, we ensure that it is backward compatible. By backward compatible, I mean truck service, which uses the latest.NET Core framework. But trip services and customer services are slightly behind in the.NET framework. So, what we have done is, we are trying to make as much best backward compatible code as we can. And that also applies for the middleware because the way we are using middleware is to ensure that the pipeline has proper authentication responses, the pipeline has proper error handling. And thirdly, the pipeline whenever a suspicious request is found or there is an auditable request. So, what we do is we randomly choose an auditable request, and that request is sent out to the audit department. You know, they'll see how and what kind of interaction has taken place. So, using that, we can also achieve uniformity. And, again, it's never a single thumb rule about it. You can always go back and see what kind of requirement you have, what kind of reusable reusability you predict and foresee. And based on that, we can always make the addition. But as I said, having a generic way of doing it is always easy because you can have a forward and backward application to be able to use those middlewares.
Okay, so monolithic, it is there are there are rules. You know, there are so many rules floating across the market, but we have to focus on the one that I actually used first of all, I used to plan a decomposition. Right? So when we are using monolithic, let's assume you're using a pack, you're using an older framework, and you're using a new framework. Decomposing is the most important part because monolithic have the mess they don't need to worry about messages, you know. They are in a single application. Everything is there. But when you go for a microservice, you break those monolithic into PCs. But this microservice should communicate between so messaging should be planned very well. Secondly, it's choosing the correct platform to upload and run the application is equally important. The third thing is to ensure that you have the common code that you are going to use. You know, they are pushed into very secure and better accessible modules, such as NuGet packages. Otherwise, you know, what will happen is you could have a lot of redundant code, you know, at times, which is not required. For example, details, you know, they don't change a lot. Right? All the details stay the same across the platform because that's what it is, the replica of the database, the DTO object. So, that is one of the factors. The fourth is because in monolithics, you know, you don't have a lot of access to caching. Caching can be very distributed in case of microservices. You can plan cache well and you have to put it forth to ensure because there could be delays in communication because they are not monolithic anymore. You know, they're communicating between different things. Of course, default tolerance is one of the advantages we are trying to exploit, but we have to plan that one as well. And lastly, you know, we have to create a strong telemetry about the communication happening and create an auditable interactions, because telemetry is required for you to know where the fault is rising because their initial stage is always difficult because the messages are not planned. We don't expect certain user behavior. We don't expect certain data to come in different fashion. So in that case, it is very important to have a solid telemetry in the picture. And last, but not the least, I would say the security has to be the cornerstone of the entire establishment because what will happen is, in case of RPM, our we were using the 3rd party Okta. Right? And now the same database was moved out to different items. So it was difficult to use one access database. That's the end of the microservice if you use the same database across. So what we did was we devised Kafka to spread out the events and any table that is pertaining to that microservice will become the DVO. And any table that is required by this microservice and it actually belongs to second, we created a different schema for practicing. And whenever the data got emitted, we will use the Kafka event to sync the database. So we know we eliminated the database syncing as well. So, yeah, these are the items I would take to convert a monolithic to microservices. It took a long time because I have experience about that. But yeah. Thank you.
Communication with your microservice using Azure Virtual Key. So it is very easy. We use the Entra ID. What we did was, you know, our entire authorization and authentication framework on Microsoft Entra, the Azure Active Directory earlier, that used to be. And based on that, we have also created matrices for the event, for the event or the message receiving and message broadcasting. Right? So for example, let's take a simple example. Even though the order or the ProBuild order is available across applications, but ProBuild is the ProBuild services' own database. So in that case, we are simply using the metrics to control that. You cannot broadcast problems, but you cannot ingest any problems because any other database that are in different microservices are metadata for it, and we don't have to consume that. So, you know, that is a way how we are using the Azure service bus. Actually, we used the Azure service bus because now everything is on Kafka. I think only one application that is using Azure service bus at this moment. I believe carrier service. Yeah. So carrier service uses the service bus to create queues, and those queues are accepted by the different microservices, right now. But we are not broadcasting any service plus messages from the other applications anymore. We are using Kafka mostly. And apart from that, you have to choose what kind of encryption you want to use if you are interested in using that. You know, you can use a private or public key-based application encryption of messages. Apart from that, there is a hash check, NuGet available to check the messages' originality. So there are few mechanisms available in place, but I did not play an active part in doing that, you know. I just use the framework that was already built before I joined, but these are the items that I'm aware of, that can happen.
So the report generator should have a single responsibility. There should be a PDF service. If the document type is a report, you need a PDF service to do this stuff for you. If you have document services, or word services, that will do for you. The report generator, and there should be document services, that would request a report generation and that will break the service into deliverables. The deliverable of the report generator service is always to communicate with the service and deliver the document and log it or audit it. There should be a different document service for word documents. The word document service will come like that. Every different type of report should have a different service to do that. That service will do only PDF. The PDF service will always work on PDF. The Word service will always work on Word. You have Excel, you have CSV, JSON. So why these services are required? Because you can always unplug it. Someday, your reports may have a macro that'll run on the Excel, and we had a couple of clients complaining about macro issues. Even though we didn't do anything, we simply discontinued sending Excels. Unless and until we resolve the bug showing potentially malicious code that'll run on the Excel, you can always plug and play. You can always plug in, you can always plug out. If there's one code, it reduces testability badly, so you have to test all the documents even though you make just one change in a PDF service. Instead, we should have all the services taken care of. If you make any change in the PDF service, you're always testing the PDF service functionality only.
So in this Azure function code excerpt, there seems to be a potential issue that could affect the scaling behavior. Can you explain what we're okay. Okay. So, see, the reason we use Azure functions is because they are small, sort of microservices. They should not take a lot of time. So if I were to work here, I would simply deliver a token to the user that would create a database and I would generate the task in the background, using a background task. Now, that background task would generate the queue item and once that queue item is complete, I would deliver the acknowledgment to the consuming service. Right? So it will be easier. It is scalable because your Azure task does not need a lot of processing because this task is just a handler. You know, it will create a log entry, and it'll process in the background. So you can keep it on low scale, but the service that actually performs the task can be horizontally scaled. So it'll become easier for you to process the queue, and this handler will just do the log entry. Right? And this way, you're applying a lazy answer, but that won't block. You know, This way, it is going to block the entire function. You're actually consuming the function for different reasons. Right? So I would use this to address the scaling issue. And apart from that, what I see is that the service bus connection is applied to it. You have my trigger, my queue item, and my logger. Yeah. So logger is also one of the functions that you should use because you are going to just keep a log entry of the task queue, and then you can continue processing it. So I think segregating this task into two functions will do. One is the background service, and they'll be vertically scaled a lot and do the real-time work. And this one will work as just a simpler gateway. Right? So this way, it will be more scalable. And that is also backward compatibility if your queue does not work for some reason. Right? This function will choke and will start choking other functions as well. But the other queue, if it is choked, you still have the queue entries. Right? Using those queue entries, you can always reprocess. I think we used this approach somewhere. I don't exactly recall the approach.
Microservices is hungry for Solid. why monolithic went away is that it was a huge architecture, and everything was inside of it. You had logging, you had caching, you had database interaction, you had the front end, and the authentication services, and we broke it, right? So we use the SOLID principles on it. That is a single responsibility, right? Then we used the inversion of control. How we use inversion control? Inversion of control is to have everything taken into context on demand. Right? So you inject everything into your context, but only when your particular service is involved. And that object will be activated, and we will do the operation and control the life cycle based on what kind of scope or scale or singleton object we are using. We have the outside-in approach, very easily observed because your core code will stay the same. Right? Even though it is distributed and it's replicated by your code, your core code stays the same. Now, when I say stay the same, that means you will use one chunk of item into the same repository that you are going to use, and that repository will not change a lot. You will always extend it based on what kind of requirement you have. You have the Liskov substitution principle. Right? And that principle would let you decide what kind of responsibility you want to give. So like in the previous question, when I said the responsibility should be delegated. Right? So you have a PDF service, you have a document service. Right? That would dictate there'll be a fair bit of delegation that will happen across the services. Right? And then you have the principle that is all good. Right? And I think that's it. Solid is the simple single responsibility. You have the SOLID principles. You have the single responsibility. You have the inversion of control. Right? So you invert the control. Your objects are not the main principle. Your abstraction is the principle. Using extraction, you can always depend and inject and create objects and use them and discard them according to the life cycle you expect it to be. So I think these four principles, I can very easily interact with microservices. And lastly, there are hybrid microservices that we use monolithic and microservices as well. Like one of my previous projects, we were using a kind of hybrid microservices. There was a lot of monolithic items that we were reusing, trying to increase the time to market. But that is what I see.
Okay. As I said, I worked Hangfire very briefly. But I understand that you can actually schedule a task, you know, create a cron job based on it. You can also do dependency injection of services that are going to be used. That's one way of doing it. We moved to the background task of the dotnet core framework, which runs in the background itself, because Hangfire is paid. So we didn't have licensing and payment issues that we ceased to work on Empire. So how we were using it? I'm talking about the specific case of happy.com, which is variable right now. So we used Hangfire earlier to schedule a background task of checking whether the user has activated the membership based on activation. We used Mailchimp to give them the required information because that would make the user adapt to the product. And since it was a revolution, we were expecting the customer to become an advocate very soon. So we were using Empire, but when we moved to microservices, we started using the background task. The background task would simply check whether there were any interactions on the customer side with the libraries of the songs or tracks that we had. Then again, we moved that to Azure function to make it more lean and not have a lot of boilerplate to run for that simple task. And lastly, background tasks are very important. For example, there is a way you can simply run a task and that would get out of your async function and still continue working on the backend. That's called the fire and forget approach. Background tasks are very important for customer interaction and everything is moved to the background. You can actually schedule a background task or even if it's Azure, you can do a cron job or create a queue based on your requirement. Whenever a queue is used, you can simply use that queue to pass the message and get the result. Let's take an example of the last time a customer used a track, which was the last location. These are some of the advantages of background tasks. But I would assume that if you have the power to use a thinner function, you know, use Azure functions. Or for example, Lambda and AWS if there is an opportunity. Because what it does, there isn't a lot of boilerplate involved. Second, it becomes your application becomes slim, you don't have a lot of items. And whenever you have to make changes to those background tasks, you don't have to worry about execution downtime or trigger the pipeline again to deliver the entire project. So according to me, that is a good approach. But there could be some cases in which Hangfire might be useful, but I am not exactly aware of.
Red disk high availability of red disk caching is when you're on Azure, you can have an application service or a Kubernetes port that runs on the port that will create a Redis distribution in the cloud. So, according to me, the best way to do it is to have AAA replicated Azure Cache. Now, by replicated Azure Cache is to have 1 or 2 ports that are syncing with each other, and they are load balanced amongst themselves. That would ensure the high availability of caching. Now, there are a few other popular caching options available, but I would use I would try to use anything that uses the JSON-based, such as Redis caching. So, to ensure high availability, we have to ensure that the port or the app of the app services that we're using this, it's happily working vertically scaled if it's possible, use the elastic plan to ensure that it is scaled up and scaled according to the traffic. The second thing is, if we are going to use the app service for example, we have to ensure that the right zone is selected. So, the geographical zones are divided across and they are properly replicated amongst themselves, and they are available in multiple zones, so that the nearer caching is available for the request becomes the choice for the caching. Third is replication should be good. Replication is the most required feature if you are using a multiple zone or multiple uploaded, Kubernetes-based, Redis application. I think these are the approaches. Again, I have not had a lot of work with it in DevOps or the back end of the Azure like this, wherein I had to actually understand the condition, try a couple of solutions, and see which one works the best, because there is no thumb rule for there could be a number of scenarios that could affect the availability issues that we're trying to get an answer of. Yeah, so these are my inputs. I don't have a lot of inputs. I would not beat around the bush, but, yeah, these two things I am aware of that should be taken care of. I think that is a generic answer for other applications as well. But for Azure Redis, this is this. Yeah, one more thing. You have to use Redis, as I know, it uses the JSON-based. Right, so try not to use Newton's option. Try to use the default JSON serializers that are available in dotnetcore nowadays. Like, it is faster than the JSON Newton's, and it is equally compatible. And there are a lot of middlewares available for that to manipulate even the pipeline. So, the best is to use the system dot JSON or system dex dot JSON that is available in dot net core, and that is better to use instead of Newton's soft JSON if you're using a dot net application. And with this, I've made my case. I think I have done fairly well, and thank you very much for the questions. They were very good and thought-provoking. See you next round.