How to return Promise after dispatching with Redux Thunk

It’s very common to use Promise with Redux Thunk, it sounds complicated but it simply just returns Promise.resolve(data) after dispatching to the reducers. Here is an example in the redux action to signup new user, then on Client just uses then(result) to manipulate the screen logic


export const signUpUser = user => {
return dispatch => {
return fetch(`http://840dff44.ngrok.io/identity/authentication/signup`, {
method: "post",
headers: {
"Content-Type": "application/json",
Accept: "json"
},
body: JSON.stringify(user)
})
.then(res => res.json())
.then(data => {
if (data.isSuccess) {
dispatch({
type: TOKEN_UPDATED,
payload: data.token
});
dispatch({
type: TOKEN_EXPIRED_ON,
payload: data.tokenExpiredOn
});
}
return Promise.resolve(data);
})
.catch(error => {
console.log(error);
return Promise.reject(error);
});
};
};

Posted by justinpham in .NET Core, AI, React - Redux, Solution Architecture, 0 comments

React-navigation 3 update the App container

There are some new changes with new react-navigation which is the main navigation system used in React Native app. The significant change which may affect your app is the app container. The app container is responsible for managing app state and linking the top-level navigator to the app environment.


import { createAppContainer } from 'react-navigation';
// you can also import from @react-navigation/native

const AppNavigator = createStackNavigator(...);

const AppContainer = createAppContainer(AppNavigator);

The AppContainer now becomes the main component loaded in the App.js without any wrapping view.

Posted by justinpham, 0 comments
Error: This experience uses an unsupported version of Expo. You may need to update Expo Client on your device.

Error: This experience uses an unsupported version of Expo. You may need to update Expo Client on your device.

Sometime when Expo releases new update with new features, you may have the issue of Expo Client expired when you run your app on Simulator. What you should do it restarts the simulator (Hardward > Restart), deleted Expo app on Simulator and run the application again. Next time when you run, it will install latest Expo client to the Simulator.

Posted by justinpham, 0 comments
Getting state error: undefined is not an object in a function

Getting state error: undefined is not an object in a function

There is a quite common issue with developers who just starting to use ReactJs. The junior and intermediate developers my team always have the issue undefined is not an object when they use this.state.[statement] in function. The problem is in Javascript in general, you need to pass the context of the App to use this keyword in the function. Most of the cases which cause the problem is developer don’t use the constructor way to declare the function which is this.function = this.function.bind(this)

Posted by justinpham, 0 comments

Azure Kubernetes Service (AKS) dashboard access error “forbidden”

There is a very common error when accessing Kubernetes Dashboard via proxy from remote machine. You can solve this error easily by granting ClusterRole to allow access to the dashboard

Create new file and insert following details

nano k8s-dashboard-access.yaml

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
labels:
k8s-app: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system


kubectl create -f kube-dashboard-access.yaml

Posted by justinpham, 0 comments

Disable check-in on TFS

As we all know that TFS is a centralised source code repository, it means everyone has access to the same source code repository. It causes lots of issues, especially when the new check-in breaks the existing code.
To implement Continuous Integration properly, the lead developer needs to setup code reviewing policy which is not allowed junior and intermediate developers check-in directly to the source code. The most effective to do it is disabling check-in permission for the normal group of developers.

Source Code Explorer -> Right click to Project and select Security

It will open TFS Web portal and disable the check-in policy for certain group of users on TFS

Posted by justinpham, 0 comments
Solution: The source file name(s) are larger than is supported by the file system

Solution: The source file name(s) are larger than is supported by the file system

When you develop application with Node.Js application, there is a very common issue with babel-cli or some other packages installed in node_modules cannot be deleted.

The easiest way to remove the folder with large source path or file name is using Git-bash on Windows or Linux


rm -rf folder-to-be-deleted

Problem solved

Posted by justinpham, 0 comments

Communication between Microservices

There are a number of discussions currently in the Dev forums and meetups about Microservices. From my point of view, it’s not a silver bullet that can solve all the problems with scalability, architecture. However, if it’s implemented correctly from architecture to coding level, it will have advantages in scaling, performance and easy deployment.

There are some similarities of Microservices and SOA with decoupled components. When I designed the SOA for the previous project, the data storage is shared within all services in SOA, it’s a very typical design of Restful API. However, the microservices have independent data storage for each service.

This post is more for the communication between microservice which normally the most confused when architect start implementing microservice.

Posted by justinpham, 0 comments

Self-hosted TFS Linux Build agent for Docker – The type initializer for ‘system.net.http.curlhandler’ threw an exception

In the previous post that I demonstrated how to create a Self-hosted Build Agent on Windows. As I implemented Docker integration to the CI/CD DevOp pipeline on TFS, I need to make sure my build agent can build and push Docker image to Registry. The simple option is to installing Docker to our VM Windows Server, however, there are lots of issues to run Docker Windows on top of VM. I decided to create Linux VM for build agent and install Docker into it.

Following the same instructions to create build agent on Windows. The only issue is to run the config.sh on Linux, it throws an System.Net.Http.CurlHandler due to missing OpenSSL. The following approach can work for both Linux or MacOS.

brew update
brew install openssl
mkdir -p /usr/local/lib
sudo ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/
sudo ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/

then install the agent again

~/myagent$ ./config.sh

To run Agent as a Service:

sudo su
./svc.sh install
./svc.sh run

Then you just need to install Docker on Linux by using following commands.

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"
sudo apt-get update

apt-cache search docker-ce

sudo apt-get install docker-ce

Test if Docker is running with the following command

docker run hello-world

Permission issue when running docker with the build agent

Assign $USER to docker group
sudo usermod -a -G docker $USER
systemctl start docker
gpasswd -a $USER docker
reboot

** To build .NET Core application with Linux build, you need to install Java (for getting the source code) and .NET Core Sdk
wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get install dotnet-sdk-2.1

Install Java

sudo add-apt-repository ppa:webupd8team/java
sudo apt update; sudo apt install oracle-java8-installer

Posted by justinpham, 0 comments
Connect to MongoDB Atlas failed when using .NET Core running on Linux

Connect to MongoDB Atlas failed when using .NET Core running on Linux

I did an experiment on .NET Core Api connect to MongoDb Atlas, when I dockerize the Core Api, it works fine on Windows container and MacOS container. However, when I started deploy to Google Cloud, there is an exception throw from API

System.TimeoutException: A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = WritableServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "ReplicaSet", Type : "ReplicaSet", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/*****-shard-00-00-*****.mongodb.net:27017" }", EndPoint: "Unspecified/*****-shard-00-00-*****.mongodb.net:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> MongoDB.Driver.MongoCommandException: Command isMaster failed: no SNI name sent, make sure using a MongoDB 3.4+ driver/shell..
at MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.ProcessReply(ConnectionId connectionId, ReplyMessage`1 reply)
at MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.<ExecuteAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.ConnectionInitializer.<InitializeConnectionAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of inner exception stack trace ---
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Servers.ServerMonitor.<HeartbeatAsync>d__27.MoveNext()" }, { ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/*****-shard-00-01-*****.mongodb.net:27017" }", EndPoint: "Unspecified/*****-shard-00-01-*****.mongodb.net:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> MongoDB.Driver.MongoCommandException: Command isMaster failed: no SNI name sent, make sure using a MongoDB 3.4+ driver/shell..
at MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.ProcessReply(ConnectionId connectionId, ReplyMessage`1 reply)
at MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.<ExecuteAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.ConnectionInitializer.<InitializeConnectionAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of inner exception stack trace ---
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Servers.ServerMonitor.<HeartbeatAsync>d__27.MoveNext()" }, { ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/*****-shard-00-02-*****.mongodb.net:27017" }", EndPoint: "Unspecified/*****-shard-00-02-*****.mongodb.net:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> MongoDB.Driver.MongoCommandException: Command isMaster failed: no SNI name sent, make sure using a MongoDB 3.4+ driver/shell..
at MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.ProcessReply(ConnectionId connectionId, ReplyMessage`1 reply)
at MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.<ExecuteAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.ConnectionInitializer.<InitializeConnectionAsync>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of inner exception stack trace ---
at MongoDB.Driver.Core.Connections.BinaryConnection.<OpenHelperAsync>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at MongoDB.Driver.Core.Servers.ServerMonitor.<HeartbeatAsync>d__27.MoveNext()" }] }.
at MongoDB.Driver.Core.Clusters.Cluster.ThrowTimeoutException(IServerSelector selector, ClusterDescription description)
at MongoDB.Driver.Core.Clusters.Cluster.WaitForDescriptionChangedHelper.HandleCompletedTask(Task completedTask)
at MongoDB.Driver.Core.Clusters.Cluster.WaitForDescriptionChanged(IServerSelector selector, ClusterDescription description, Task descriptionChangedTask, TimeSpan timeout, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Clusters.Cluster.SelectServer(IServerSelector selector, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Bindings.WritableServerBinding.GetWriteChannelSource(CancellationToken cancellationToken)
at MongoDB.Driver.Core.Operations.CreateIndexesOperation.Execute(IWriteBinding binding, CancellationToken cancellationToken)
at MongoDB.Driver.OperationExecutor.ExecuteWriteOperation[TResult](IWriteBinding binding, IWriteOperation`1 operation, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.ExecuteWriteOperation[TResult](IWriteOperation`1 operation, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.MongoIndexManager.CreateMany(IEnumerable`1 models, CancellationToken cancellationToken)
at MongoDB.Driver.MongoIndexManagerBase`1.CreateOne(IndexKeysDefinition`1 keys, CreateIndexOptions options, CancellationToken cancellationToken)

It’s a common error with C# Mongo Driver, because The .NET Core library 2.0 does not support the SNI TLS extension on Linux and OSX.

To fix the issue, I changed the base image on Dockerfile to microsoft/dotnet:2.1-aspnetcore-runtime. If you use Linux, use apt-get dotnet-runtime-2.1.

 

Posted by justinpham, 0 comments