001/*
002 * (C) Copyright 2010-2016 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 */
019
020package org.nuxeo.connect.client.status;
021
022import java.util.Calendar;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.nuxeo.connect.connector.CanNotReachConnectServer;
027import org.nuxeo.connect.connector.ConnectClientVersionMismatchError;
028import org.nuxeo.connect.connector.ConnectSecurityError;
029import org.nuxeo.connect.connector.ConnectServerError;
030import org.nuxeo.connect.identity.LogicalInstanceIdentifier;
031import org.nuxeo.connect.registration.ConnectRegistrationService;
032import org.nuxeo.runtime.api.Framework;
033
034/**
035 * @author Tiry (tdelprat@nuxeo.com)
036 */
037public class ConnectStatusHolder {
038
039    protected static ConnectStatusHolder instance;
040
041    protected SubscriptionStatusWrapper instanceStatus;
042
043    protected static final Log log = LogFactory.getLog(ConnectStatusHolder.class);
044
045    protected static final int REFRESH_PERIOD_MINUTES = 10;
046
047    public static ConnectStatusHolder instance() {
048        if (instance == null) {
049            instance = new ConnectStatusHolder();
050        }
051        return instance;
052    }
053
054    protected ConnectRegistrationService getService() {
055        return Framework.getService(ConnectRegistrationService.class);
056    }
057
058    /**
059     * @deprecated Since 9.2, use {@link #isRegistered()} instead.
060     */
061    @Deprecated
062    public boolean isRegistred() {
063        return isRegistered();
064    }
065
066    /**
067     * @since 9.2
068     */
069    public boolean isRegistered() {
070        // no cache needed
071        return getService().isInstanceRegistered();
072    }
073
074    public SubscriptionStatusWrapper getStatus() {
075
076        // get status (possibility from cache)
077        SubscriptionStatusWrapper lastStatus = getStatus(false);
078
079        // check freshness
080        Calendar oldestStatusDate = Calendar.getInstance();
081        oldestStatusDate.add(Calendar.MINUTE, -REFRESH_PERIOD_MINUTES);
082        if (lastStatus == null || lastStatus.refreshDate.before(oldestStatusDate)) {
083            // try to refresh
084            SubscriptionStatusWrapper refreshStatus = getStatus(true);
085            // keep last success status in case of error
086            if ((refreshStatus == null || refreshStatus.isError()) && lastStatus != null && !lastStatus.isError()) {
087                instanceStatus = lastStatus;
088                instanceStatus.refreshDate = Calendar.getInstance();
089            }
090        }
091
092        return instanceStatus;
093    }
094
095    public void flush() {
096        instanceStatus = null;
097    }
098
099    public SubscriptionStatusWrapper getStatus(boolean forceRefresh) {
100        if (instanceStatus == null || forceRefresh) {
101            if (isRegistered()) {
102                try {
103                    instanceStatus = new SubscriptionStatusWrapper(getService().getConnector().getConnectStatus());
104                } catch (CanNotReachConnectServer e) {
105                    log.warn("Cannot reach Nuxeo Online Services", e);
106                    instanceStatus = new SubscriptionStatusWrapper("Nuxeo Online Services is not reachable");
107                    instanceStatus.canNotReachConnectServer = true;
108                } catch (ConnectClientVersionMismatchError e) {
109                    log.warn(
110                            "Nuxeo Connect Client does not have the required version to communicate with Nuxeo Online Services",
111                            e);
112                    instanceStatus = new SubscriptionStatusWrapper(e.getMessage());
113                    instanceStatus.versionMismatch = true;
114                } catch (ConnectSecurityError e) {
115                    log.warn("Cannot authenticate against Nuxeo Online Services", e);
116                    instanceStatus = new SubscriptionStatusWrapper(e);
117                } catch (ConnectServerError e) {
118                    log.error("Error while calling Nuxeo Online Services", e);
119                    instanceStatus = new SubscriptionStatusWrapper(e.getMessage());
120                }
121            } else {
122                instanceStatus = new UnresgistedSubscriptionStatusWrapper();
123            }
124        }
125        return instanceStatus;
126    }
127
128    /**
129     * Returns the registration expiration timestamp included in the CLID, or -1 if the CLID cannot be loaded or doesn't
130     * include the expiration timestamp (old v0 format).
131     *
132     * @since 10.2
133     */
134    public long getRegistrationExpirationTimestamp() {
135        LogicalInstanceIdentifier clid = getService().getCLID();
136        if (clid == null) {
137            return -1;
138        }
139        String clid1 = clid.getCLID1();
140        if (clid1.length() == 36) {
141            // no expiration timestamp (old v0 format)
142            return -1;
143        }
144        // check format
145        String[] split = clid1.split("\\.");
146        if (split.length != 3) {
147            // invalid format
148            return -1;
149        }
150        // return expiration timestamp
151        return Long.parseLong(split[1]);
152    }
153
154}