001package org.apache.turbine.services.uniqueid; 002 003 004import java.nio.charset.StandardCharsets; 005 006/* 007 * Licensed to the Apache Software Foundation (ASF) under one 008 * or more contributor license agreements. See the NOTICE file 009 * distributed with this work for additional information 010 * regarding copyright ownership. The ASF licenses this file 011 * to you under the Apache License, Version 2.0 (the 012 * "License"); you may not use this file except in compliance 013 * with the License. You may obtain a copy of the License at 014 * 015 * http://www.apache.org/licenses/LICENSE-2.0 016 * 017 * Unless required by applicable law or agreed to in writing, 018 * software distributed under the License is distributed on an 019 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 020 * KIND, either express or implied. See the License for the 021 * specific language governing permissions and limitations 022 * under the License. 023 */ 024 025 026import java.security.MessageDigest; 027import java.util.concurrent.atomic.AtomicInteger; 028 029import org.apache.commons.codec.binary.Base64; 030import org.apache.logging.log4j.LogManager; 031import org.apache.logging.log4j.Logger; 032import org.apache.turbine.Turbine; 033import org.apache.turbine.services.InitializationException; 034import org.apache.turbine.services.TurbineBaseService; 035import org.apache.turbine.util.GenerateUniqueId; 036 037/** 038 * <p> This is an implementation of {@link UniqueIdService}. 039 * 040 * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> 041 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 042 * @version $Id$ 043 */ 044public class TurbineUniqueIdService 045 extends TurbineBaseService 046 implements UniqueIdService 047{ 048 /** Logging */ 049 private static final Logger log = LogManager.getLogger(TurbineUniqueIdService.class); 050 051 /** The identifier of this instance of turbine. */ 052 private static String turbineId = "UNKNOWN"; 053 054 private static String turbineURL = "UNKNOWN"; 055 056 private static final AtomicInteger counter = new AtomicInteger(); 057 058 059 /** 060 * <p> Initializes the service upon first Turbine.doGet() 061 * invocation. 062 */ 063 @Override 064 public void init() 065 throws InitializationException 066 { 067 try 068 { 069 counter.set(0); 070 071 // This might be a problem if the unique Id Service runs 072 // before Turbine got its first request. In this case, 073 // getDefaultServerData will return just a dummy value 074 // which is the same for all instances of Turbine. 075 // 076 // TODO This needs definitely further working. 077 turbineURL = Turbine.getDefaultServerData().toString(); 078 079 MessageDigest md = MessageDigest.getInstance("MD5"); 080 byte [] bytesId = md.digest(turbineURL.getBytes(StandardCharsets.UTF_8)); 081 turbineId = new String(Base64.encodeBase64(bytesId), 082 StandardCharsets.UTF_8); 083 084 log.info("This is Turbine instance running at: {}", turbineURL); 085 log.info("The instance id is #{}", turbineId); 086 setInit(true); 087 } 088 catch (Exception e) 089 { 090 throw new InitializationException( 091 "Could not initialize TurbineUniqueId Service", e); 092 } 093 } 094 095 /** 096 * <p> Writes a message to the log upon system shutdown. 097 */ 098 @Override 099 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}