Saturday, February 11, 2023

Thinking about sinking boat

It's been so long, since I have shared my thoughts, and I don't think it's worth of anything, and I have no idea what I'd like to get from it.
And still, I've got few ideas, that of course look useful to me, but it's too late to start over with something new.

Zaznam o nehode (Accident record) online

Mobile app (or smart webapp), based on zaznam o nehode PDF, with user stored details about their vehicle, exchanged by counterparts of accident, signed with face-and-id photo, drawing with drag and rotate vehicles, cross-road and signs and finger brushing hit places, integrated with police and insurance, assistance and repair services, free for personal use, paid by business, carsharing.

I wrote to ozvemese@ideasense.cz, in response to Learning which one will not get out of ones mind (in Czech) (I had the idea back in 2017), but they need settled business idea, not just thoughts.

Tax automation.

Fill tax declaration automatically basing on bank account statement. Categorize income by source type Parse insurance, kindergarden documents for tax deduction.

May be integrated with bank app, and pay tax and preliminary tax automatically.

Slicing Pie for Jira.

Project funding, coin pool, distribute on log work timeSpent/estimate (less/more if estimate is changed), mining on issue created/estimated, tatum api with private key (ssh does not pass one, session key instead) address by public key from github/bitbucket.

"An embedded token contains information about which workers have worked on the product and been involved in transporting it by truck to the harbour and the ship etc. ... Since the contracts with the suppliers are defined as smart contracts in a distributed ledger technology network, all payments are automated".
See also 

Investing advisory


Is it good for me to invest, considiring my current cost of living, income, personal and world expectations, based on known facts.

I start from the fact that investing is a science that not everyone has to understand, but they have to invest, and it can be quite modeled, for example, a family as a business, has income and expenses, and certainly has phases of the life cycle, and these are the parameters of the investment model, to that we add distribution according to modern knowledge, so that family will need an investment reserve, about some multiple of expenses, and the rest can be invested according to distribution based on life stage and market conditions.

Tuesday, August 26, 2014

Playing with real-time content delivery (WebSocket)

This time I'd like to share some results of experimenting with Firebase and Socket.IO while playing with real-time content delivery with WebSockets a bit.

FireBase - NoSQL database, has a powerful API to store and sync data in real-time using WebSocket. It also has perfect Security Rules system, which allows to restrict read and write access to data in the manner I was dreaming about when playing with CouchDB back in 2011. The goal was to let everyone access only his or her data right from the browser. So, here is an example of security rules that suites this need:
{
  "rules": {
    ".read": false,
    ".write": false,
    "users": {
      "$user": {
        ".read": "auth.uid === $user",
        ".write": "auth.uid === $user"
      }
    },
    "data": {
      "$data": {
        ".read": "auth.uid === data.child('uid').val()",
        ".write": "auth.uid === data.child('uid').val()"
      }
    }
  }
}

Then there are many ways to authenticate. With Simple Login, it could be static web site hosted on FireBase, similarly to CouchApp, fantastic! But I decided to try custom authentication, and integrate Firebase with Atlassian Connect Add-On in Node.js using atlassian-connect-express.

Here is relevant part of client javascript. That simple to get own data:

addon.js

  var rootRef = new Firebase("https://example-multi-tenant.firebaseio.com/data");
  rootRef.auth(firebaseToken, function(error) {
    rootRef.on("value", function(snapshot) {
      var data = snapshot.val();

And firebaseToken is generated serverside basing on authentication information provided by Atlassian Connect. So I map clientKey to uid for Firebase security rules:

routes/index.js:

    var FirebaseTokenGenerator = require("firebase-token-generator");
    var tokenGenerator = new FirebaseTokenGenerator(process.env.FIREBASE_SECRET);

    app.get('/whoslooking', addon.authenticate(), function (req, res) {

        var clientKey = req.session.clientKey;
        var firebaseToken = tokenGenerator.createToken({ "uid": clientKey });

I did not come to particular useful use-case yet, and have tried to clone existing Who's Looking add-on for JIRA, but there must be better ideas to try out with this approach.

For such simple case, it looked overcomplicated to me, so I've given Socket.IO a try, and ended-up actually within Engine.IO, which is the WebSocket semantics transport layer Socket.IO uses.

The main interesting part for me is authenticating connections, so that only add-on could connect. Here is the trick to leverage atlassian-connect-express authentication within allowRequest function that can decide whether to allow WebSocket request or not in app.js:
var authentication = require('atlassian-connect-express/lib/middleware/authentication.js');
var authenticationHandler = authentication.authenticate(addon, true);

var server = http.createServer(app);
var io = require('engine.io').attach(server, {allowRequest: function(req, next) {
  req.query = req._query;
  req.header = function(name) {
    return req.headers[name];
  };
  var res = {
    send: function(code, msg) {
      next(msg); // error
    },
    setHeader: function() {}
  };
  authenticationHandler(req, res, function(err) {
    next(err, !err); // success
  });
}});

Then Who's Looking logic itself is very simple. State is just kept in memory serverside, and is updated when connection is open or closed, and every time simple message is sent to client with all users currently looking at JIRA issue, no heart-beat (or long polling) and database. Nice and easy, isn't it?

Such add-on can be deployed to Heroku, by the way, it has support for WebSockets already!

Monday, March 10, 2014

Building website with Punch

Finally, I've got something, hopefully useful, to share. Today I would like to describe fully automated and completely free way of publishing and hosting static website with Punch and Jenkins.

Punch


Punch is a simple, intuitive web publishing framework, like, probably better known, Jekyll. I've found it better for myself because of possibility to write custom content handlers. Overall,  I think, Punch can be viewed as more generic website publishing framework than Jekyll. Also it's Node.js application.

Though I was missing automatic publishing like gh-pages. But I have recently come across nice post about Building a private gh-pages clone with dexy and gitlab, which mainly inspired me to investigate this drawback.

DEV@Cloud (Jenkins)


Jenkins is the #1 open source continuous integration tool. And it's offered by Cloudbees as a Service, also well known as DEV@Cloud. Luckily, among great bunch of possibilities, it allows to build Node.js projects, which is the core part of my solution, though very simple.

My manual build shell script is as follows:
curl -s -o use-node https://repository-cloudbees.forge.cloudbees.com/distributions/ci-addons/node/use-node
NODE_VERSION=0.10.4 . ./use-node
npm install -g punch
npm install
punch p
The last command generates and publishes site. Punch supports publishing to Amazon S3 or to a custom server with SFTP out of the box, but with GitHub or Bitbucket you can host your static website for free, see GitHub Pages again and Publishing a Website on Bitbucket. So, we'll need to define custom publishing strategy.

Punch git publisher


I have not found available punch-git-publisher useful - at the moment of writing it is unfinished. So I've created own git publishing strategy: punch-git-publisher.js. It needs to be configured in punch config.json as follows:
"plugins": {
    "publishers": {
        "git_strategy": "./lib/punch-git-publisher.js" 
    }
},

"publish": {
    "strategy": "git_strategy",
    "options": {
        "repo_url": "git@bitbucket.org:azhdanov/azhdanov.bitbucket.org.git"
    }
}

Brining it all together


The most interesting part, automating :) I host my website project on Bitbucket, similarly to website itself. Although I believe it will work with GitHub in very similar way for User or Organization and Project pages, however for the latter you will need to modify punch-git-publisher.js to commit in gh-pages branch.

Below is few simple steps to make your changes in punch project trigger automatic build and publishing:
  1. Obtain Jenkins API key. For DEV@Cloud see https://<account>.ci.cloudbees.com/user/<the-user-portion-of-your-email>/configure, e.g. https://avalez.ci.cloudbees.com/user/azhdanov/configure.
  2. Enable 'Trigger builds remotely' in your Jenkins project configuration.
  3. Add commit hook, e.g. see Jenkins hook. For DEV@Cloud EndPoint must be similarly to above, i.e. https://<the-user-portion-of-your-email>:<apitoken>@<account>.ci.cloudbees.com, e.g. https://azhdanov:***@avalez.ci.cloudbees.com
  4. Add Jenkins ssh public key to your Bitbucket account to let build push generated website content to the repository. Here is good writeup for Github: How to use private github repositories with cloudbees, and Bitbucket: Add an SSH key to an account.
Now, just do your changes, commit, push, and if you're lucky, you get your website updated in a minute, all like Using Jekyll with GitHub Pages. Here is the overall picture:



Let me know how it works for you ;)

References

  1.  punch-git-publisher.js

Thursday, November 1, 2012

Fun at Java One in San Francisco and after

Beside having fun in San Francisco, I've presented at Java One with my more experienced colleague Mitesh Meswani! Recording of our BOF2737 "Developing Multitenant Applications with HK2 2.0 and EclipseLink" session is available here, see Media on right pane.

It was my first talk, and it went quite smoothly, due to small audience :) But the number (20) matched our expectations! HK2 is definitely not so known and sexy, as HTML5, NoSQL and Scala. But we've got something to go on.

Looks like there is no much demand for sharing run-time between tenants. However data isolation draws big interest, so including EclipseLink, was useful for the audience.

From other hand many people think of multi-tenancy in the same way - running single instance of the application for multiple clients. That's great! And everybody tries it differently.

It's worth to mention IBM's CON6465 - JVM Support for Multitenant Applications
talk about multi-tenant JVM. But beside IBM there is Waratek that does very good job in context of multi-tenancy in JVM too, but I have not seen their session, if there was any. And there might be more of course.

Other, not related to multi-tenancy but to CDI, CON7780 - Designing Java EE Applications in the Age of CDI, draw my interest. And caused to check that it's also possible to @Inject Logger with HK2! See my git commit#4dcad7b6e3 for example!. However, it brought rather difficult problem, multi-tenant logging. Well, there are much more problems like this, of course.

Also, I liked Venkat Subramaniam the most! And again, his CON3454 - Concurrency Without Pain in Pure Java makes me to highlight that HK2 also provides STM without pain in even more pure Java. In order to change any configuration element, one must start a configuration transaction that ensures restricted access to the configuration. The following demonstrates transaction invocation for mutating injected configuration object:

@Inject
HttpListener httpListener;

ConfigSupport.apply(new SingleCodeCode<HttpListener>() {
        public Object run(HttpListener wListener) {
                wListener.setPort("8080");
        }, httpListener);


Hopefully there will be something more, stay tuned!

Friday, August 10, 2012

Multi-Tenant Programming Model

This time, as promised, I'd like to describe one of a few possible models of developing Multi-Tenant applications, with HK2 and EclipseLink.

Disclaimer: HK2 and EclipseLink don't have to be used together. This model is not intended for any PaaS. And this post does not cover all aspects of developing multi-tenant applications. This model attempts to simplify programmer experience when developing multi-tenant application with single application instance per tenant approach.

Let me start with less familiar HK2 first. It is an implementation of the JSR 330: Dependency Injection standard for Java.  I won't repeat it's documentation, but highlight its configuration subsystem. HK2 offers support for software configuration in xml file. E.g. you can have pure class with few annotations:

@Configured
public interface HttpServer extends ConfigBeanProxy {
    @Attribute
    String getName();
    void setName(String name);
}

Then it is mapped to xml:
<http-server name="..." />

It is similar to JAXB, without explicit binding, or rather with binding by convention, and with restricted write access. Finally, with HK2, consumer may have configuration injected:

@Service
public class Foo {
    @Inject
    HttpServer httpServer;
}

See my previous post for how to start with HK2 support for xml configuration.

Recent version 2.2 of HK2 among other things, introduces @Proxiable annotation. Combined with custom @Scope-d annotation, and applied to configuration object, it allows to have once injected configuration be different at execution time depending on the state of the system. So configuration may be different for Alice and Bob, tenants of your application.

See Tenant Managed Scope Example for details on how to implement that @TenantScoped trick. And try it yourself, check out examples/ctm@hk2.java.net.

From other hand, hopefully better known, EclipseLink is implementation of Java persistence standard. Version 2.4 (Juno) brings better support for Multi-Tenancy. Beside Documentation and Examples I would like to recommend full-stack MySports example, provided by EclipseLink team also. Shortly, EclipseLink allows to impelement persistence with table per tenant or single table, using column discriminator and gives few architectural options:
  • Dedicated Persistence Unit - separate persistence-unit in persistence.xml, so application must request the correct PersistenceContext or PersistenceUnit for tenant.
  • Persistence Context per Tenant - single persistence unit definition in the persistence.xml and a shared persistence unit (EntityManagerFactory and cache).
  • Persistence Unit per Tenant - single persistence unit defined in the persistence.xml and different persistence contexts with their own caches are created per tenant.

And now, applying @TenantScoped @Proxiable @Scope from HK2 example above to one of the EclipseLink multi-tenant architecture, HK2 will substitute persistence context for tenenat at runtime, like this:

public class TenantEntityManagerFactory implements Factory<entitymanager> {
    @Inject
    private TenantManager manager;

    ...

    @TenantScoped
    public EntityManager provide() {

        String currentTenant = manager.getCurrentTenant();
        Map properties = new HashMap();
        properties.put(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT,
                 currentTenant);
        properties.put(PersistenceUnitProperties.SESSION_NAME, currentTenant);
        EntityManager em = Persistence.createEntityManagerFactory("multi-tenant-pu",
                 properties).createEntityManager();
        return em;
    }
}

So consuming code can have EntityManager provided once by HK2 dependency injection, and have it different depending on current tenant, thread safe! E.g.

public class Foo {
    @Inject
    EntityManager entityManager;

    public void testPersistence() {
        // assume tenantManager.setCurrentTenant() is called somewhere in stack

        entityManager.getTransaction().begin();
        Customer customer = new Customer();
        customer.setName("ACME");
        entityManager.persist(customer);
        entityManager.getTransaction().commit(); 
    }
}

See my eclipselink-hk2@github for working example. It also demonstrates  usage of Extensible Entities.

That's it. Let me know if you try this model.

Monday, August 6, 2012

Quick TIP: View diff attached to JIRA issue

I often like to see diff attached to a JIRA issue, but if you click attachment link, browser usually suggests to download attachment. Though if you right-click the link, copy link location and then paste into browser address bar and prefix it with view-source: it will simply display it, e.g. (copy & paste it into browser address bar):

view-source:http://java.net/jira/secure/attachment/50568/working.diff

Diff taken from http://java.net/jira/browse/HK2-63

Convenient, isn't it?

Tuesday, July 24, 2012

About SaaS

This time I'd like to share my views about different approaches to SaaS. Remember from my previous post - SaaS (just) scales on demand, and when executed, it is somehow isolated from other tenants of the "same" software.

1) PaaS Ready, i.e. software that is ready to be installed/deployed to PaaS. This can be for example a Ruby on Rails application ready to be deployed to Heroku, or java web application to be deployed to Jelastic. It means Software Instance per tenant. E.g. origin code can be hosted on GitHub, you clone it, customize and deploy to PaaS. This is not much different from classic hosting. Beside the fact that it will scale!

Oh, I should have mentioned the simplest approach, used at some of existing SaaS marketplaces. A SaaS markeplace company lets you use a software without being bothered with its installing and deploying. It does not necessarily need to be SaaS actually. I think this is very close to Amazon Marketplace, when they sell pre-configured Amozon Machine Images (AMI). Interesting, but something different. Or non-SaaS approach to SaaS :)

2) Business SaaS, let's call it. SalesForce, WSO2 and may be many others, allows to build SaaS at their platform online. WSO2 has somewhat better case, when one can deploy special type of application - carbon application, but you still need to configure resources needed for the application, like database or web services. Well, how is it different from the first case? At Heroku or Jelastic you may also need to setup resources needed for the application. Is it different because SalesForce and WSO2 applications share execution environment? In my thoughts, difference is rather that you don't have standalone codebase that you can just deploy into PaaS, you build your software with their online tools.

Well, with WSO2 it's not so bad (from software developer point of view, of course). Developers create carbon applications "offline".  Also, what's interesting, setting carbon.enable.saas=true in web.xml, WSO2 application becomes multi-tenant. But looks like WSO2 tenant context can not be leveraged in the application. Developer still needs  to have a multi-tenant architecture for his application, like multi-tenant data store , or anything else. Also it's not clear if only super tenant can run saas enabled carbon application.

Note, I was trying hard to understand whether SalesForce allows to create multi-tenant application. Looks like not. Also it does not seem possible to deploy any redistributable package.

3) Multi-tenant SaaS - tenant aware application, such that each tenant will share the instance of running software. It may look the same for tenants, but technically it will be one deployed instance, serving needs of different tenants. Isolation happens on application level, similarly to WSO2 all resources are shared, but everything is executed isolated. Why it's needed? For better resource utilization. Notice, it comes from previous case. It also can be PaaS Ready application.

Well, the latter is actually area of my research, for those curious why I'm thinking so much about cloud computing. Hopefully next post(s) will be about programming model(s) of multi-tenant applications in Java. Though don't expect it to be "ready" for any PaaS yet.

Off-topic, it could be interesting to talk about sharing revenue between PaaS provider developer of SaaS. It's clearly possible in non-SaaS case, like being an AMI vendor. It's also likely possible in second type. And it's completely up to software developer in third case.

In 2nd case, it rather depends on how billing works in WSO2-like saas enabled case. Will tenant be billed for using super-tenant resources, and/or will he have his own resources?

I'm rather inclined to 3rd type, multi-tenant SaaS, which leaves revenue sharing out :) And hope to write about it. Is there someone excited?

And picture!