Using Firebase Test Lab for Testing test cases of Phimpme Android

As now we started writing some test cases for Phimpme Android. While running my instrumentation test case, I saw a tab of Cloud Testing in Android Studio. This is for Firebase Test Lab. Firebase Test Lab provides cloud-based infrastructure for testing Android apps. Everyone doesn’t have every devices of all the android versions. But testing on all of them is equally important. How I used test lab in Phimpme Run your first test on Firebase Select Test Lab in your project on the left nav on the Firebase console, and then click Run a Robo test. The Robo test automatically explores your app on wide array of devices to find defects and report any crashes that occur. It doesn’t require you to write test cases. All you need is the app's APK. Nothing else is needed to use Robo test. Upload your Application's APK (app-debug-unaligned.apk) in the next screen and click Continue Configure the device selection, a wide range of devices and all API levels are present there. You can save the template for future use. Click on start test to start testing. It will start the tests and show the real time progress as well. Using Firebase Test Lab from Android Studio It required Android Studio 2.0+. You needs to edit the configuration of Android Instrumentation test. Select the Firebase Test Lab Device Matrix under the Target. You can configure Matrix, matrix is actually on what virtual and physical devices do you want to run your test. See the below screenshot for details. Note: You need to enable the firebase in your project So using test lab on firebase we can easily test the test cases on multiple devices and make our app more scalable. Resources: Firebase Documentation: https://firebase.google.com/docs/test-lab/ Youtube Video: https://youtu.be/4_ZEEX1x17k Run a Robo test: https://firebase.google.com/docs/test-lab/robo-ux-test

Continue ReadingUsing Firebase Test Lab for Testing test cases of Phimpme Android

Image Loading in Open Event Organizer Android App using Glide

Open Event Organizer is an Android App for the Event Organizers and Entry Managers. Open Event API Server acts as a backend for this App. The core feature of the App is to scan a QR code from the ticket to validate an attendee's check in. Other features of the App are to display an overview of sales and ticket management. As per the functionality, the performance of the App is very important. The App should be functional even on a weak network. Talking about the performance, the image loading part in the app should be handled efficiently as it is not an essential part of the functionality of the App. Open Event Organizer uses Glide, a fast and efficient image loading library created by Sam Judd. I will be talking about its implementation in the App in this blog. First part is the configuration of the glide in the App. The library provides a very easy way to do that. Your app needs to implement a class named AppGlideModule using annotations provided by the library and it generates a glide API which can be used in the app for all the image loading stuff. The AppGlideModule implementation in the Orga App looks like: @GlideModule public final class GlideAPI extends AppGlideModule { @Override public void registerComponents(Context context, Glide glide, Registry registry) { registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory()); } // TODO: Modify the options here according to the need @Override public void applyOptions(Context context, GlideBuilder builder) { int diskCacheSizeBytes = 1024 * 1024 * 10; // 10mb builder.setDiskCache(new InternalCacheDiskCacheFactory(context, diskCacheSizeBytes)); } @Override public boolean isManifestParsingEnabled() { return false; } }   This generates the API named GlideApp by default in the same package which can be used in the whole app. Just make sure to add the annotation @GlideModule to this implementation which is used to find this class in the app. The second part is using the generated API GlideApp in the app to load images using URLs. Orga App uses data binding for layouts. So all the image loading related code is placed at a single place in DataBinding class which is used by the layouts. The class has a method named setGlideImage which takes an image view, an image URL, a placeholder drawable and a transformation. The relevant code is: private static void setGlideImage(ImageView imageView, String url, Drawable drawable, Transformation<Bitmap> transformation) { if (TextUtils.isEmpty(url)) { if (drawable != null) imageView.setImageDrawable(drawable); return; } GlideRequest<Drawable> request = GlideApp .with(imageView.getContext()) .load(Uri.parse(url)); if (drawable != null) { request .placeholder(drawable) .error(drawable); } request .centerCrop() .transition(withCrossFade()) .transform(transformation == null ? new CenterCrop() : transformation) .into(imageView); }   The method is very clear. First, the URL is checked for nullability. If null, the drawable is set to the imageview and method returns. Usage of GlideApp is simpler. Pass the URL to the GlideApp using the method with which returns a GlideRequest which has operators to set other required options like transitions, transformations, placeholder etc. Lastly, pass the imageview using into operator. By default, Glide uses HttpURLConnection…

Continue ReadingImage Loading in Open Event Organizer Android App using Glide

Basics behind school level experiments with PSLab

Electronics is a fascinating subject to most kids. Turning on a LED bulb, making a simple circuit will make them dive into much more interesting areas in the field of electronics. PSLab android application with the help of PSLab device implements a set of experiments whose target audience is school children. To make them more interested in science and electronics, there are several experiments implemented such as measuring body resistance, lemon cell experiment etc. This blog post brings out the basics in implementing these type of experiments and pre-requisite. Lemon Cell Experiment Lemon Cell experiment is a basic experiment which will make school kids interested in science experiments. The setup requires a fresh lemon and a pair of nails which is used to drive into the lemon as illustrated in the figure. The implementation in PSLab android application uses it’s Channel 1. The cell generates a low voltage which can be detected using the CH1 pin of PSLab device and it is sampled at a rate of 10 to read an accurate result. float voltage = (float) scienceLab.getVoltage("CH1", 10); 2000 instances are recorded using this method and plotted against each instance. The output graph will show a decaying graph of voltage measured between the nails driven into the lemon. for (int i = 0; i < timeAxis.size(); i++) { temp.add(new Entry(timeAxis.get(i), voltageAxis.get(i))); } Human Body Resistance Measurement Experiment This experiment attracts most of the young people to do electronic experiments. This is implemented in the PSLab android application using Channel 3 and the Programmable Voltage Source 3 which can generate voltage up to 3.3V. The experiment requires a human with drippy palms so it makes a good conductance between device connection and the body itself. The PSLab device has an internal resistance of 1M Ohms connected with the Channel 3 pin. Experiment requires a student to hold two wires with the metal core exposed; in both hands. One wire is connected to PV3 pin when the other wire is connected to CH3 pin. When a low voltage is supplied from the PV3 pin, due to heavy resistance in body and the PSLab device, a small current in the range of nano amperes will flow through body. Using the reading from CH3 pin and the following calculation, body resistance can be measured. voltage = (float) scienceLab.getVoltage("CH3", 100); current = voltage / M; resistance = (M * (PV3Voltage - voltage)) / voltage; This operation is executed inside a while loop to provide user with a continuous set of readings. Using Java threads there is a workaround to implement the functionalities inside the while loop without overwhelming the system. First step is to create a object without any attribute. private final Object lock = new Object(); Java threads use synchronized methods where other threads won’t start until the first thread is completed or paused operation. We make use of that technique to provide enough time to read CH3 pin and display output. while (true) { new MeasureResistance().execute(); synchronized (lock) { try { lock.wait();…

Continue ReadingBasics behind school level experiments with PSLab

Adding Static Code Analyzers in Open Event Orga Android App

This week, in Open Event Orga App project (Github Repo), we wanted to add some static code analysers that run on each build to ensure that the app code is free of potential bugs and follows a certain style. Codacy handles a few of these things, but it is quirky and sometimes produces false positives. Furthermore, it is not a required check for builds so errors can creep in gradually. We chose checkstyle, PMD and Findbugs for static analysis as they are most popular for Java. The area they work on kind of overlaps but gives security regarding code quality. Findbugs actually analyses the bytecode instead of source code to find possible JVM bugs. Adding dependencies The first step was to add the required dependencies. We chose the library android-check as it contained all 3 libraries and was focused on Android and easily configurable. First, we add classpath in project level build.gradle dependencies { classpath 'com.noveogroup.android:check:1.2.4' }   Then, we apply the plugin in app level build.gradle apply plugin: 'com.noveogroup.android.check'   This much is enough to get you started, but by default, the build will not fail if any violations are found. To change this behaviour, we add this block in app level build.gradle check { abortOnError true }   There are many configuration options available for the library. Do check out the project github repo using the link provided above Configuration The default configuration is of easy level, and will be enough for most projects, but it is of course configurable. So we took the default hard configs for 3 analysers and disabled properties which we did not need. The place you need to store the config files is the config folder in either root project directory or the app directory. The name of the config file should be checkstyle.xml, pmd.xml and findbugs.xml These are the default settings and you can obviously configure them by following the instructions on the project repo Checkstyle For checkstyle, you can find the easy and hard configuration here The basic principle is that if you need to add a check, you include a module like this: <module name="NewlineAtEndOfFile" />   If you want to modify the default value of some property, you do it like this: <module name="RegexpSingleline"> <property name="format" value="\s+$" /> <property name="minimum" value="0" /> <property name="maximum" value="0" /> <property name="message" value="Line has trailing spaces." /> <property name="severity" value="info" /> </module>   And if you want to remove a check, you can ignore it like this: <module name="EqualsHashCode"> <property name="severity" value="ignore" /> </module>   It’s pretty straightforward and easy to configure. Findbugs For findbugs, you can find the easy and hard configuration here Findbugs configuration exists in the form of filters where we list resources it should skip analyzing, like: <Match> <Class name="~.*\.BuildConfig" /> </Match>   If we want to ignore a particular pattern, we can do so like this: <!-- No need to force hashCode for simple models --> <Match> <Bug pattern="HE_EQUALS_USE_HASHCODE " /> </Match>   Sometimes, you’d want to only…

Continue ReadingAdding Static Code Analyzers in Open Event Orga Android App

Adding TextDrawable as a PlaceHolder in Open Event Android App

The Open Event Android project has a fragment for showing speakers of the event. Each Speaker model has image-url which is used to fetch the image from server and load in the ImageView. In some cases it is possible that image-url is null or client is not able to fetch the image from the server because of the network problem. So in these cases showing Drawable which contains First letters of the first name and the last name along with a color background gives great UI and UX. In this post I explain how to add TextDrawable as a placeholder in the ImageView using TextDrawable library. 1. Add dependency In order to use TextDrawable in your app add following dependencies in your app module’s build.gradle file. dependencies { compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' } 2. Create static TextDrawable builder Create static method in the Application class which returns the builder object for creating TextDrawables. We are creating static method so that the method can be used all over the App. private static TextDrawable.IShapeBuilder textDrawableBuilder; public static TextDrawable.IShapeBuilder getTextDrawableBuilder() { if (textDrawableBuilder == null) { textDrawableBuilder = TextDrawable.builder(); } return textDrawableBuilder; } This method first checks if the builder object is null or not and then initialize it if null. Then it returns the builder object. 3.  Create and initialize TextDrawable object Now create a TextDrawable object and initialize it using the builder object. The Builder has methods like buildRound(), buildRect() and buildRoundRect() for making drawable round, rectangle and rectangle with rounded corner respectively. Here we are using buildRect() to make the drawable rectangle. TextDrawable drawable = OpenEventApp.getTextDrawableBuilder() .buildRect(Utils.getNameLetters(name), ColorGenerator.MATERIAL.getColor(name)); The buildRect() method takes two arguments one is String text which will be used as a text in the drawable and second is int color which will be used as a background color of the drawable. Here ColorGenerator.MATERIAL returns material color for given string. 4.  Create getNameLetters()  method The getNameLetters(String name) method should return the first letters of the first name and last name as String. Example, if the name is “Shailesh Baldaniya” then it will return “SB”. public static String getNameLetters(String name) { if (isEmpty(name)) return "#"; String[] strings = name.split(" "); StringBuilder nameLetters = new StringBuilder(); for (String s : strings) { if (nameLetters.length() >= 2) return nameLetters.toString().toUpperCase(); if (!isEmpty(s)) { nameLetters.append(s.trim().charAt(0)); } } return nameLetters.toString().toUpperCase(); } Here we are using split method to get the first name and last name from the name. The charAt(0) gives the first character of the string. If the name string is null then it will return “#”.    5.  Use Drawable Now after creating the TextDrawable object we need to load it as a placeholder in the ImageView for this we are using Picasso library. Picasso.with(context) .load(image-url) .placeholder(drawable) .error(drawable) .into(speakerImage); Here the placeholder() method displays drawable while the image is being loaded. The error() method displays drawable when the requested image could not be loaded when the device is offline. SpeakerImage is an ImageView in which we want to load the image. Conclusion TextDrawable is…

Continue ReadingAdding TextDrawable as a PlaceHolder in Open Event Android App

Data Access Layer in Open Event Organizer Android App

Open Event Organizer is an Android App for Organizers and Entry Managers. Its core feature is scanning a QR Code to validate Attendee Check In. Other features of the App are to display an overview of sales and tickets management. The App maintains a local database and syncs it with the Open Event API Server. The Data Access Layer in the App is designed such that the data is fetched from the server or taken from the local database according to the user's need. For example, simply showing the event sales overview to the user will fetch the data from the locally saved database. But when the user wants to see the latest data then the App need to fetch the data from the server to show it to the user and also update the locally saved data for future reference. I will be talking about the data access layer in the Open Event Organizer App in this blog. The App uses RxJava to perform all the background tasks. So all the data access methods in the app return the Observables which is then subscribed in the presenter to get the data items. So according to the data request, the App has to create the Observable which will either load the data from the locally saved database or fetch the data from the API server. For this, the App has AbstractObservableBuilder class. This class gets to decide which Observable to return on a data request. Relevant Code: final class AbstractObservableBuilder<T> { ... ... @NonNull private Callable<Observable<T>> getReloadCallable() { return () -> { if (reload) return Observable.empty(); else return diskObservable .doOnNext(item -> Timber.d("Loaded %s From Disk on Thread %s", item.getClass(), Thread.currentThread().getName())); }; } @NonNull private Observable<T> getConnectionObservable() { if (utilModel.isConnected()) return networkObservable .doOnNext(item -> Timber.d("Loaded %s From Network on Thread %s", item.getClass(), Thread.currentThread().getName())); else return Observable.error(new Throwable(Constants.NO_NETWORK)); } @NonNull private <V> ObservableTransformer<V, V> applySchedulers() { return observable -> observable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @NonNull public Observable<T> build() { if (diskObservable == null || networkObservable == null) throw new IllegalStateException("Network or Disk observable not provided"); return Observable .defer(getReloadCallable()) .switchIfEmpty(getConnectionObservable()) .compose(applySchedulers()); } }   The class is used to build the Abstract Observable which contains both types of Observables, making data request to the API server and the locally saved database. Take a look at the method build. Method getReloadCallable provides an observable which will be the default one to be subscribed which is a disk observable which means data is fetched from the locally saved database. The method checks parameter reload which if true suggests to make the data request to the API server or else to the locally saved database. If the reload is false which means data can be fetched from the locally saved database, getReloadCallable returns the disk observable and the data will be fetched from the locally saved database. If the reload is true which means data request must be made to the API server, then the method returns an empty observable. The method getConnectionObservable returns a network observable…

Continue ReadingData Access Layer in Open Event Organizer Android App

Introduction To Kotlin in SUSI Android App

Lately, we wrote some of the code of SUSI Android App in Kotlin. Kotlin is a very similar language to Java but with much more advantages than Java. It is easy to adapt and learn. There is no doubt that Kotlin is better than Java but with the announcement of Kotlin Support in Google IO’17 for Android development, Kotlin seems a decent way to write code for an Android App. Advantages of Kotlin over Java Reduce Boilerplate Code: It helps making development of app faster as it reduces more than 20 percent of boilerplate code. Writing long statements again and again is a headache for developers. Kotlin comes to rescue in that situation. Removes Null Pointer Exception: Once a large company faced millions of dollars of loss due to null pointer exception. It causes crashes of apps more often than anything else. Thus Kotlin helps in Null checks and makes app free from Null pointer Exceptions. Interoperable with Java: Kotlin code and Java code are interoperable. Which means you can write half your code in kotlin and half in Java and it will work like a charm. You can call java methods from Kotlin code and vice versa. So, you can simply move your existing Java based app to Kotlin slowly making your app always running. Lambda and Inline functions: Yes, Kotlin also has functionalities from functional programming languages. Mainly and most widely used feature of those languages is Lambda functions. Direct Reference of Views by Id: You do not need to write findViewById(R.id.view_name) or use any other library like Butterknife for view binding. You can simply use the view by its id. No semicolon:  Last but not the least, you do not need to add a semicolon after each statement. In fact, you do not need to add semicolon at all. Setting up Android Studio to work with Kotlin If you have latest Android Studio Canary Version, there is already a build support for Kotlin in it. You need not do anything in that case. But if you don't have the Canary version, you can add Kotlin Plugin in your Android Studio. Follow the below steps to do that. Install the Kotlin Plugin: Android Studio → Preferences… →Plugins → Browse Repository → type “Kotlin” in search box → install Restart your Android Studio and Rebuild the project. Everything else is already set up in SUSI Android App but if you want to do it for your other apps, follow this link. Implementation in SUSI Android App So, I am not going to give unnecessary code but will point out specific things where Kotlin helped a lot to reduce unnecessary code and made the code compact. 1. Listeners: Earlier with Java Button signup = (Button) findViewById(R.id.sign_up); signup.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(LoginActivity.this, SignUpActivity.class)); } }); Now, with Kotlin fun signUp() { sign_up.setOnClickListener { startActivity(Intent(this@LoginActivity, SignUpActivity::class.java)) } } 2. Models With Java public class MapData { private double latitude; private double longitude; private double zoom; public…

Continue ReadingIntroduction To Kotlin in SUSI Android App

API Error Handling in the Open Event Organizer Android App

Open Event Organizer is an Android App for Organizers and Entry Managers. Open Event API server acts as a backend for this App. So basically the App makes data requests to the API and in return, the API performs required actions on the data and sends back the response to the App which is used to display relevant info to the user and to update the App's local database. The error responses returned by the API need to parse and show the understandable error message to the user. The App uses Retrofit+OkHttp for making network requests to the API. Hence the request method returns a Throwable in the case of an error in the action. The Throwable contains a string message which can be get using the method named getMessage. But the message is not understandable by the normal user. Open Event Organizer App uses ErrorUtils class for this work. The class has a method which takes a Throwable as a parameter and returns a good error message which is easier to understand to the user. Relevant code: public final class ErrorUtils { public static final int BAD_REQUEST = 400; public static final int UNAUTHORIZED = 401; public static final int FORBIDDEN = 403; public static final int NOT_FOUND = 404; public static final int METHOD_NOT_ALLOWED = 405; public static final int REQUEST_TIMEOUT = 408; private ErrorUtils() { // Never Called } public static String getMessage(Throwable throwable) { if (throwable instanceof HttpException) { switch (((HttpException) throwable).code()) { case BAD_REQUEST: return "Something went wrong! Please check any empty field if a form."; case UNAUTHORIZED: return "Invalid Credentials! Please check your credentials."; case FORBIDDEN: return "Sorry, you are not authorized to make this request."; case NOT_FOUND: return "Sorry, we couldn't find what you were looking for."; case METHOD_NOT_ALLOWED: return "Sorry, this request is not allowed."; case REQUEST_TIMEOUT: return "Sorry, request timeout. Please retry after some time."; default: return throwable.getMessage(); } } return throwable.getMessage(); } } ErrorUtils.java app/src/main/java/org/fossasia/openevent/app/common/utils/core/ErrorUtils.java All the error codes are stored as static final fields. It is always a good practice to follow a making the constructor private for a utility class to make sure the class is never initialized anywhere in the app. The method getMessage takes a Throwable and checks if it is an instance of the HttpException to get an HTTP error code. Actually, there are two exceptions - HttpException and IOException. The prior one is returned from the server. In the method by using the error codes, relevant good error messages are returned which are shown to the user in a snackbar layout. It is always a good practice to show a more understandable user-friendly error messages than simply the default ones which are not clear to the normal user. Links: 1. List of the HTTP Client Error Codes - Wikipedia Link 2. Class Throwable javadoc

Continue ReadingAPI Error Handling in the Open Event Organizer Android App

Using Mosquitto as a Message Broker for MQTT in loklak Server

In loklak server, messages are collected from various sources and indexed using Elasticsearch. To know when a message of interest arrives, users can poll the search endpoint. But this method would require a lot of HTTP requests, most of them being redundant. Also, if a user would like to collect messages for a particular topic, he would need to make a lot of requests over a period of time to get enough data. For GSoC 2017, my proposal was to introduce stream API in the loklak server so that we could save ourselves from making too many requests and also add many use cases. Mosquitto is Eclipse’s project which acts as a message broker for the popular MQTT protocol. MQTT, based on the pub-sub model, is a lightweight and IOT friendly protocol. In this blog post, I will discuss the basic setup of Mosquitto in the loklak server. Installation and Dependency for Mosquitto The installation process of Mosquitto is very simple. For Ubuntu, it is available from the pre installed PPAs - sudo apt-get install mosquitto Once the message broker is up and running, we can use the clients to connect to it and publish/subscribe to channels. To add MQTT client as a project dependency, we can introduce following line in Gradle dependencies file - compile group: 'net.sf.xenqtt', name: 'xenqtt', version: '0.9.5' [SOURCE] After this, we can use the client libraries in the server code base. The MQTTPublisher Class The MQTTPublisher class in loklak would provide an interface to perform basic operations in MQTT. The implementation uses AsyncClientListener to connect to Mosquitto broker - AsyncClientListener listener = new AsyncClientListener() { // Override methods according to needs }; [SOURCE] The publish method for the class can be used by other components of the project to publish messages on the desired channel - public void publish(String channel, String message) { this.mqttClient.publish(new PublishMessage(channel, QoS.AT_LEAST_ONCE, message)); } [SOURCE] We also have methods which allow publishing of multiple messages to multiple channels in order to increase the functionality of the class. Starting Publisher with Server The flags which signal using of streaming service in loklak are located in conf/config.properties. These configurations are referred while initializing the Data Access Object and an MQTTPublisher is created if needed - String mqttAddress = getConfig("stream.mqtt.address", "tcp://127.0.0.1:1883"); streamEnabled = getConfig("stream.enabled", false); if (streamEnabled) { mqttPublisher = new MQTTPublisher(mqttAddress); } [SOURCE] The mqttPublisher can now be used by other components of loklak to publish messages to the channel they want. Adding Mosquitto to Kubernetes Since loklak has also a nice Kubernetes setup, it was very simple to introduce a new deployment for Mosquitto to it. Changes in Dockerfile The Dockerfile for master deployment has to be modified to discover Mosquitto broker in the Kubernetes cluster. For this purpose, corresponding flags in config.properties have to be changed to ensure that things work fine - sed -i.bak 's/^\(stream.enabled\).*/\1=true/' conf/config.properties && \ sed -i.bak 's/^\(stream.mqtt.address\).*/\1=mosquitto.mqtt:1883/' conf/config.properties && \ [SOURCE] The Mosquitto broker would be available at mosquitto.mqtt:1883 because of the service that is created…

Continue ReadingUsing Mosquitto as a Message Broker for MQTT in loklak Server

Deploying loklak Server on Kubernetes with External Elasticsearch

Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications. - kubernetes.io Kubernetes is an awesome cloud platform, which ensures that cloud applications run reliably. It runs automated tests, flawless updates, smart roll out and rollbacks, simple scaling and a lot more. So as a part of GSoC, I worked on taking the loklak server to Kubernetes on Google Cloud Platform. In this blog post, I will be discussing the approach followed to deploy development branch of loklak on Kubernetes. New Docker Image Since Kubernetes deployments work on Docker images, we needed one for the loklak project. The existing image would not be up to the mark for Kubernetes as it contained the declaration of volumes and exposing of ports. So I wrote a new Docker image which could be used in Kubernetes. The image would simply clone loklak server, build the project and trigger the server as CMD - FROM alpine:latest ENV LANG=en_US.UTF-8 ENV JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8 WORKDIR /loklak_server RUN apk update && apk add openjdk8 git bash && \ git clone https://github.com/loklak/loklak_server.git /loklak_server && \ git checkout development && \ ./gradlew build -x test -x checkstyleTest -x checkstyleMain -x jacocoTestReport && \ # Some Configurations and Cleanups CMD ["bin/start.sh", "-Idn"] [SOURCE] This image wouldn’t have any volumes or exposed ports and we are now free to configure them in the configuration files (discussed in a later section). Building and Pushing Docker Image using Travis To automatically build and push on a commit to the master branch, Travis build is used. In the after_success section, a call to push Docker image is made. Travis environment variables hold the username and password for Docker hub and are used for logging in - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD [SOURCE] We needed checks there to ensure that we are on the right branch for the push and we are not handling a pull request - # Build and push Kubernetes Docker image KUBERNETES_BRANCH=loklak/loklak_server:latest-kubernetes-$TRAVIS_BRANCH KUBERNETES_COMMIT=loklak/loklak_server:kubernetes-$TRAVIS_COMMIT if [ "$TRAVIS_BRANCH" == "development" ]; then docker build -t loklak_server_kubernetes kubernetes/images/development docker tag loklak_server_kubernetes $KUBERNETES_BRANCH docker push $KUBERNETES_BRANCH docker tag $KUBERNETES_BRANCH $KUBERNETES_COMMIT docker push $KUBERNETES_COMMIT elif [ "$TRAVIS_BRANCH" == "master" ]; then # Build and push master else echo "Skipping Kubernetes image push for branch $TRAVIS_BRANCH" fi [SOURCE] Kubernetes Configurations for loklak Kubernetes cluster can completely be configured using configurations written in YAML format. The deployment of loklak uses the previously built image. Initially, the image tagged as latest-kubernetes-development is used - apiVersion: apps/v1beta1 kind: Deployment metadata: name: server namespace: web spec: replicas: 1 template: metadata: labels: app: server spec: containers: - name: server image: loklak/loklak_server:latest-kubernetes-development ... [SOURCE] Readiness and Liveness Probes Probes act as the top level tester for the health of a deployment in Kubernetes. The probes are performed periodically to ensure that things are working fine and appropriate steps are taken if they fail. When a new image is updated, the older pod still runs and servers the requests. It is replaced by the new ones only when the probes are…

Continue ReadingDeploying loklak Server on Kubernetes with External Elasticsearch