org.entcore.cursus.controllers.CursusController.java Source code

Java tutorial

Introduction

Here is the source code for org.entcore.cursus.controllers.CursusController.java

Source

/*
 * Copyright  Rgion Nord Pas de Calais-Picardie.
 *
 * This file is part of OPEN ENT NG. OPEN ENT NG is a versatile ENT Project based on the JVM and ENT Core Project.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation (version 3 of the License).
 *
 * For the sake of explanation, any module that communicate over native
 * Web protocols, such as HTTP, with OPEN ENT NG is outside the scope of this
 * license and could be license under its own terms. This is merely considered
 * normal use of OPEN ENT NG, and does not fall under the heading of "covered work".
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

package org.entcore.cursus.controllers;

import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import io.vertx.core.http.*;
import org.entcore.common.http.filter.ResourceFilter;
import org.entcore.common.user.UserInfos;
import org.entcore.common.user.UserUtils;
import org.entcore.common.utils.MapFactory;
import org.entcore.cursus.filters.CursusFilter;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import org.vertx.java.core.http.RouteMatcher;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import fr.wseduc.rs.*;
import fr.wseduc.security.ActionType;
import fr.wseduc.security.SecuredAction;
import fr.wseduc.webutils.Either;
import fr.wseduc.webutils.http.BaseController;

public class CursusController extends BaseController {

    //Service
    private final CursusService service = new CursusService();

    //Webservice client & endpoint
    private HttpClient cursusClient;
    private final URL wsEndpoint;

    //Webservice auth request conf
    private final JsonObject authConf;

    //Auth reply data & wallets list
    private Map<String, String> cursusMap;

    @Override
    public void init(Vertx vertx, JsonObject config, RouteMatcher rm,
            Map<String, fr.wseduc.webutils.security.SecuredAction> securedActions) {
        super.init(vertx, config, rm, securedActions);

        HttpClientOptions cursusClientOptions = new HttpClientOptions().setDefaultHost(wsEndpoint.getHost());

        if ("https".equals(wsEndpoint.getProtocol())) {
            cursusClientOptions.setSsl(true).setTrustAll(true).setDefaultPort(443);
        } else {
            cursusClientOptions.setDefaultPort(wsEndpoint.getPort() == -1 ? 80 : wsEndpoint.getPort());
        }
        cursusClient = vertx.createHttpClient(cursusClientOptions);

        cursusMap = MapFactory.getSyncClusterMap("cursusMap", vertx, false);

        /*
        service.refreshToken(new Handler<Boolean>() {
           public void handle(Boolean res) {
        if(!res)
           log.error("[Cursus][refreshToken] Error while retrieving the Token.");
        else
           log.info("[Cursus][refreshToken] Token refreshed.");
           }
        });
        */
        if (cursusMap.containsKey("wallets"))
            return;
        service.refreshWallets(new Handler<Boolean>() {
            public void handle(Boolean res) {
                if (!res)
                    log.error("[Cursus][refreshWallets] Error while retrieving the wallets list.");
                else
                    log.info("[Cursus][refreshWallets] Wallets list refreshed.");
            }
        });

    }

    public CursusController(URL endpoint, final JsonObject conf) {
        wsEndpoint = endpoint;
        authConf = conf;
    }

    @Put("/refreshToken")
    @SecuredAction(value = "", type = ActionType.RESOURCE)
    @ResourceFilter(CursusFilter.class)
    public void refreshToken(final HttpServerRequest request) {
        service.refreshToken(new Handler<Boolean>() {
            public void handle(Boolean success) {
                if (success) {
                    ok(request);
                } else {
                    badRequest(request);
                }
            }
        });

    }

    @Put("/refreshWallets")
    @SecuredAction(value = "", type = ActionType.RESOURCE)
    @ResourceFilter(CursusFilter.class)
    public void refreshWallets(final HttpServerRequest request) {
        service.refreshWallets(new Handler<Boolean>() {
            public void handle(Boolean success) {
                if (success) {
                    ok(request);
                } else {
                    badRequest(request);
                }
            }
        });
    }

    @Get("/sales")
    @SecuredAction(value = "", type = ActionType.AUTHENTICATED)
    public void getSales(final HttpServerRequest request) {
        final String cardNb = request.params().get("cardNb");
        if (cardNb == null) {
            badRequest(request);
            return;
        }

        service.getUserInfo(cardNb, new Handler<Either<String, JsonArray>>() {
            public void handle(Either<String, JsonArray> result) {
                if (result.isLeft()) {
                    badRequest(request);
                    return;
                }

                final String id = result.right().getValue().getJsonObject(0).getInteger("id").toString();
                String birthDateEncoded = result.right().getValue().getJsonObject(0).getString("dateNaissance");
                try {
                    birthDateEncoded = birthDateEncoded.replace("/Date(", "");
                    birthDateEncoded = birthDateEncoded.substring(0, birthDateEncoded.indexOf("+"));
                    final Date birthDate = new Date(Long.parseLong(birthDateEncoded));

                    UserUtils.getUserInfos(eb, request, new Handler<UserInfos>() {
                        public void handle(UserInfos infos) {
                            DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                            try {
                                Date sessionBirthDate = format.parse(infos.getBirthDate());
                                if (sessionBirthDate.compareTo(birthDate) == 0) {
                                    service.getSales(id, cardNb, new Handler<Either<String, JsonArray>>() {
                                        public void handle(Either<String, JsonArray> result) {
                                            if (result.isLeft()) {
                                                badRequest(request);
                                                return;
                                            }

                                            JsonObject finalResult = new JsonObject()
                                                    .put("wallets", new JsonArray(cursusMap.get("wallets")))
                                                    .put("sales", result.right().getValue());

                                            renderJson(request, finalResult);
                                        }
                                    });
                                } else {
                                    badRequest(request);
                                }
                            } catch (ParseException e) {
                                badRequest(request);
                                return;
                            }
                        }
                    });
                } catch (Exception e) {
                    badRequest(request);
                }
            }
        });
    }

    /**
     * Inner service class.
     */
    private class CursusService {

        public void authWrapper(final Handler<Boolean> handler) {
            JsonObject authObject = new JsonObject();
            if (cursusMap.get("auth") != null)
                authObject = new JsonObject(cursusMap.get("auth"));

            Long currentDate = Calendar.getInstance().getTimeInMillis();
            Long expirationDate = 0l;
            if (authObject != null)
                expirationDate = authObject.getLong("tokenInit", 0l) + authConf.getLong("tokenDelay", 1800000l);

            if (expirationDate < currentDate) {
                log.info("[Cursus] Token seems to have expired.");
                refreshToken(handler);
            } else {
                handler.handle(true);
            }
        }

        public void refreshToken(final Handler<Boolean> handler) {
            HttpClientRequest req = cursusClient.post(
                    wsEndpoint.getPath() + "/AuthentificationImpl.svc/json/AuthentificationExtranet",
                    new Handler<HttpClientResponse>() {
                        public void handle(HttpClientResponse response) {
                            if (response.statusCode() >= 300) {
                                handler.handle(false);
                                log.error(response.statusMessage());
                                return;
                            }

                            response.bodyHandler(new Handler<Buffer>() {
                                public void handle(Buffer body) {
                                    log.info("[Cursus][refreshToken] Token refreshed.");

                                    JsonObject authData = new JsonObject(body.toString());
                                    authData.put("tokenInit", new Date().getTime());
                                    cursusMap.put("auth", authData.encode());
                                    handler.handle(true);
                                }
                            });
                        }
                    });
            req.putHeader(HttpHeaders.ACCEPT, "application/json; charset=UTF-8").putHeader(HttpHeaders.CONTENT_TYPE,
                    "application/json");
            req.end(authConf.encode());
        }

        public void refreshWallets(final Handler<Boolean> handler) {
            authWrapper(new Handler<Boolean>() {
                public void handle(Boolean gotToken) {
                    if (!gotToken) {
                        handler.handle(false);
                        return;
                    }

                    int schoolYear = Calendar.getInstance().get(Calendar.MONTH) < 8
                            ? Calendar.getInstance().get(Calendar.YEAR) - 1
                            : Calendar.getInstance().get(Calendar.YEAR);

                    /* JSON */
                    JsonObject reqBody = new JsonObject();
                    reqBody.put("numSite", authConf.getString("numSite"))
                            .put("tokenId", new JsonObject(cursusMap.get("auth")).getString("tokenId"))
                            .put("typeListes",
                                    new JsonArray().add(new JsonObject().put("typeListe", "LST_PORTEMONNAIE")
                                            .put("param1", schoolYear + "-" + (schoolYear + 1))));
                    /*      */

                    /* XML /
                    String reqBody =
                       "<tem:GetListes xmlns:tem=\"http://tempuri.org/\" xmlns:wcf=\"http://schemas.datacontract.org/2004/07/WcfExtranetChequeBL.POCO.Parametres\">" +
                          "<tem:numSite>"+ authConf.getString("numSite") +"</tem:numSite>" +
                          "<tem:typeListes>" +
                    "<wcf:RechercheTypeListe>" +
                       "<wcf:typeListe>LST_PORTEMONNAIE</wcf:typeListe>" +
                       "<wcf:param1>"+ schoolYear + "-" + (schoolYear + 1) +"</wcf:param1>" +
                    "</wcf:RechercheTypeListe>" +
                          "</tem:typeListes>" +
                          "<tem:tokenId>"+ authData.getString("tokenId") +"</tem:tokenId>" +
                       "</tem:GetListes>";
                    /*      */

                    HttpClientRequest req = cursusClient.post(
                            wsEndpoint.getPath() + "/GeneralImpl.svc/json/GetListes",
                            new Handler<HttpClientResponse>() {
                                public void handle(HttpClientResponse response) {
                                    if (response.statusCode() >= 300) {
                                        handler.handle(false);
                                        log.error(response.statusMessage());
                                        return;
                                    }

                                    response.bodyHandler(new Handler<Buffer>() {
                                        public void handle(Buffer body) {
                                            try {
                                                cursusMap.put("wallets", new JsonArray(body.toString())
                                                        .getJsonObject(0).getJsonArray("parametres").encode());
                                                handler.handle(true);
                                            } catch (Exception e) {
                                                handler.handle(false);
                                            }
                                        }
                                    });
                                }
                            });
                    req.putHeader(HttpHeaders.ACCEPT, "application/json; charset=UTF-8")
                            .putHeader(HttpHeaders.CONTENT_TYPE, "application/json");
                    req.end(reqBody.encode());
                }
            });
        };

        public void getUserInfo(final String cardNb, final Handler<Either<String, JsonArray>> handler) {
            authWrapper(new Handler<Boolean>() {
                public void handle(Boolean gotToken) {
                    if (!gotToken) {
                        handler.handle(new Either.Left<String, JsonArray>(
                                "[Cursus][getUserInfo] Issue while retrieving token."));
                        return;
                    }

                    JsonObject reqBody = new JsonObject();
                    reqBody.put("numSite", authConf.getString("numSite"))
                            .put("tokenId", new JsonObject(cursusMap.get("auth")).getString("tokenId"))
                            .put("filtres", new JsonObject().put("numeroCarte", cardNb));

                    HttpClientRequest req = cursusClient.post(
                            wsEndpoint.getPath() + "/BeneficiaireImpl.svc/json/GetListeBeneficiaire",
                            new Handler<HttpClientResponse>() {
                                public void handle(HttpClientResponse response) {
                                    if (response.statusCode() >= 300) {
                                        handler.handle(new Either.Left<String, JsonArray>("invalid.status.code"));
                                        return;
                                    }

                                    response.bodyHandler(new Handler<Buffer>() {
                                        public void handle(Buffer body) {
                                            handler.handle(new Either.Right<String, JsonArray>(
                                                    new JsonArray(body.toString())));
                                        }
                                    });
                                }
                            });
                    req.putHeader(HttpHeaders.ACCEPT, "application/json; charset=UTF-8")
                            .putHeader(HttpHeaders.CONTENT_TYPE, "application/json");
                    req.end(reqBody.encode());
                }
            });
        }

        public void getSales(final String numeroDossier, final String cardNb,
                final Handler<Either<String, JsonArray>> handler) {
            authWrapper(new Handler<Boolean>() {
                public void handle(Boolean gotToken) {
                    if (!gotToken) {
                        handler.handle(new Either.Left<String, JsonArray>(
                                "[Cursus][getSales] Issue while retrieving token."));
                        return;
                    }

                    JsonObject reqBody = new JsonObject();
                    reqBody.put("numeroSite", authConf.getString("numSite"))
                            .put("tokenId", new JsonObject(cursusMap.get("auth")).getString("tokenId"))
                            .put("filtresSoldesBeneficiaire", new JsonObject().put("numeroDossier", numeroDossier)
                                    .put("numeroCarte", cardNb));

                    HttpClientRequest req = cursusClient.post(
                            wsEndpoint.getPath() + "/BeneficiaireImpl.svc/json/GetSoldesBeneficiaire",
                            new Handler<HttpClientResponse>() {
                                public void handle(HttpClientResponse response) {
                                    if (response.statusCode() >= 300) {
                                        handler.handle(new Either.Left<String, JsonArray>("invalid.status.code"));
                                        return;
                                    }

                                    response.bodyHandler(new Handler<Buffer>() {
                                        public void handle(Buffer body) {
                                            handler.handle(new Either.Right<String, JsonArray>(
                                                    new JsonArray(body.toString())));
                                        }
                                    });
                                }
                            });
                    req.putHeader(HttpHeaders.ACCEPT, "application/json; charset=UTF-8")
                            .putHeader(HttpHeaders.CONTENT_TYPE, "application/json");
                    req.end(reqBody.encode());
                }
            });
        }

    }
}