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: TurbineUniqueIdService.java 1870549 2019-11-28 09:37:33Z tv $ 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 }