001package org.apache.turbine.services.uniqueid;
002
003
004/*
005 * Licensed to the Apache Software Foundation (ASF) under one
006 * or more contributor license agreements.  See the NOTICE file
007 * distributed with this work for additional information
008 * regarding copyright ownership.  The ASF licenses this file
009 * to you under the Apache License, Version 2.0 (the
010 * "License"); you may not use this file except in compliance
011 * with the License.  You may obtain a copy of the License at
012 *
013 *   http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing,
016 * software distributed under the License is distributed on an
017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018 * KIND, either express or implied.  See the License for the
019 * specific language governing permissions and limitations
020 * under the License.
021 */
022
023
024import java.security.MessageDigest;
025
026
027import org.apache.commons.codec.binary.Base64;
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030
031import org.apache.turbine.Turbine;
032import org.apache.turbine.services.InitializationException;
033import org.apache.turbine.services.TurbineBaseService;
034import org.apache.turbine.util.GenerateUniqueId;
035
036/**
037 * <p> This is an implementation of {@link UniqueIdService}.
038 *
039 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
040 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
041 * @version $Id: TurbineUniqueIdService.java 1812601 2017-10-19 06:40:28Z gk $
042 */
043public class TurbineUniqueIdService
044        extends TurbineBaseService
045        implements UniqueIdService
046{
047    /** Logging */
048    private static Log log = LogFactory.getLog(TurbineUniqueIdService.class);
049
050    /** The identifier of this instance of turbine. */
051    protected static String turbineId = "UNKNOWN";
052
053    protected static String turbineURL = "UNKNOWN";
054
055    protected static int counter;
056
057
058    /**
059     * <p> Initializes the service upon first Turbine.doGet()
060     * invocation.
061     */
062    @Override
063    public void init()
064            throws InitializationException
065    {
066        try
067        {
068            // This might be a problem if the unique Id Service runs
069            // before Turbine got its first request. In this case,
070            // getDefaultServerData will return just a dummy value
071            // which is the same for all instances of Turbine.
072            //
073            // TODO This needs definitely further working.
074            String url = Turbine.getDefaultServerData().toString();
075
076            MessageDigest md = MessageDigest.getInstance("MD5");
077            byte [] bytesId = md.digest(url.getBytes("UTF-8"));
078            turbineId = new String(Base64.encodeBase64(bytesId),"UTF-8");
079
080            log.info("This is Turbine instance running at: " + url);
081            log.info("The instance id is #" + turbineId);
082            setInit(true);
083        }
084        catch (Exception e)
085        {
086            throw new InitializationException(
087                    "Could not initialize TurbineUniqueId Service", e);
088        }
089    }
090
091    /**
092     * <p> Writes a message to the log upon system shutdown.
093     */
094    @Override
095    public void shutdown()
096    {
097        log.info("Turbine instance running at " + turbineURL + " shutting down.");
098    }
099
100    /**
101     * <p> Returns an identifier of this Turbine instance that is unique
102     * both on the server and worldwide.  This identifier is computed
103     * as an MD5 sum of the URL (including schema, address, port if
104     * different that 80/443 respecively, context and servlet name).
105     * There is an overwhelming probalility that this id will be
106     * different that all other Turbine instances online.
107     *
108     * @return A String with the instance identifier.
109     */
110    public String getInstanceId()
111    {
112        return turbineId;
113    }
114
115    /**
116     * <p> Returns an identifier that is unique within this turbine
117     * instance, but does not have random-like apearance.
118     *
119     * @return A String with the non-random looking instance
120     * identifier.
121     */
122    public String getUniqueId()
123    {
124        int current;
125        synchronized (TurbineUniqueIdService.class)
126        {
127            current = counter++;
128        }
129        String id = Integer.toString(current);
130
131        // If you manage to get more than 100 million of ids, you'll
132        // start getting ids longer than 8 characters.
133        if (current < 100000000)
134        {
135            id = ("00000000" + id).substring(id.length());
136        }
137        return id;
138    }
139
140    /**
141     * <p> Returns a unique identifier that looks like random data.
142     *
143     * @return A String with the random looking instance identifier.
144     */
145    public String getPseudorandomId()
146    {
147        return GenerateUniqueId.getIdentifier();
148    }
149}