1 package org.apache.turbine.services.uniqueid;
2
3
4 import java.nio.charset.StandardCharsets;
5
6 /*
7 * Licensed to the Apache Software Foundation (ASF) under one
8 * or more contributor license agreements. See the NOTICE file
9 * distributed with this work for additional information
10 * regarding copyright ownership. The ASF licenses this file
11 * to you under the Apache License, Version 2.0 (the
12 * "License"); you may not use this file except in compliance
13 * with the License. You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing,
18 * software distributed under the License is distributed on an
19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20 * KIND, either express or implied. See the License for the
21 * specific language governing permissions and limitations
22 * under the License.
23 */
24
25
26 import java.security.MessageDigest;
27 import java.util.concurrent.atomic.AtomicInteger;
28
29 import org.apache.commons.codec.binary.Base64;
30 import org.apache.logging.log4j.LogManager;
31 import org.apache.logging.log4j.Logger;
32 import org.apache.turbine.Turbine;
33 import org.apache.turbine.services.InitializationException;
34 import org.apache.turbine.services.TurbineBaseService;
35 import org.apache.turbine.util.GenerateUniqueId;
36
37 /**
38 * <p> This is an implementation of {@link UniqueIdService}.
39 *
40 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
41 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
42 * @version $Id$
43 */
44 public class TurbineUniqueIdService
45 extends TurbineBaseService
46 implements UniqueIdService
47 {
48 /** Logging */
49 private static final Logger log = LogManager.getLogger(TurbineUniqueIdService.class);
50
51 /** The identifier of this instance of turbine. */
52 private static String turbineId = "UNKNOWN";
53
54 private static String turbineURL = "UNKNOWN";
55
56 private static final AtomicInteger counter = new AtomicInteger();
57
58
59 /**
60 * <p> Initializes the service upon first Turbine.doGet()
61 * invocation.
62 */
63 @Override
64 public void init()
65 throws InitializationException
66 {
67 try
68 {
69 counter.set(0);
70
71 // This might be a problem if the unique Id Service runs
72 // before Turbine got its first request. In this case,
73 // getDefaultServerData will return just a dummy value
74 // which is the same for all instances of Turbine.
75 //
76 // TODO This needs definitely further working.
77 turbineURL = Turbine.getDefaultServerData().toString();
78
79 MessageDigest md = MessageDigest.getInstance("MD5");
80 byte [] bytesId = md.digest(turbineURL.getBytes(StandardCharsets.UTF_8));
81 turbineId = new String(Base64.encodeBase64(bytesId),
82 StandardCharsets.UTF_8);
83
84 log.info("This is Turbine instance running at: {}", turbineURL);
85 log.info("The instance id is #{}", turbineId);
86 setInit(true);
87 }
88 catch (Exception e)
89 {
90 throw new InitializationException(
91 "Could not initialize TurbineUniqueId Service", e);
92 }
93 }
94
95 /**
96 * <p> Writes a message to the log upon system shutdown.
97 */
98 @Override
99 public void shutdown()
100 {
101 log.info("Turbine instance running at {} shutting down.", turbineURL);
102 }
103
104 /**
105 * <p> Returns an identifier of this Turbine instance that is unique
106 * both on the server and worldwide. This identifier is computed
107 * as an MD5 sum of the URL (including schema, address, port if
108 * different that 80/443 respectively, context and servlet name).
109 * There is an overwhelming probability that this id will be
110 * different that all other Turbine instances online.
111 *
112 * @return A String with the instance identifier.
113 */
114 @Override
115 public String getInstanceId()
116 {
117 return turbineId;
118 }
119
120 /**
121 * <p> Returns an identifier that is unique within this turbine
122 * instance, but does not have random-like appearance.
123 *
124 * @return A String with the non-random looking instance
125 * identifier.
126 */
127 @Override
128 public String getUniqueId()
129 {
130 int current = counter.getAndIncrement();
131 String id = Integer.toString(current);
132
133 // If you manage to get more than 100 million of ids, you'll
134 // start getting ids longer than 8 characters.
135 if (current < 100000000)
136 {
137 id = ("00000000" + id).substring(id.length());
138 }
139 return id;
140 }
141
142 /**
143 * <p> Returns a unique identifier that looks like random data.
144 *
145 * @return A String with the random looking instance identifier.
146 */
147 @Override
148 public String getPseudorandomId()
149 {
150 return GenerateUniqueId.getIdentifier();
151 }
152 }