com.edmunds.etm.common.impl.UrlTokenRepository.java Source code

Java tutorial

Introduction

Here is the source code for com.edmunds.etm.common.impl.UrlTokenRepository.java

Source

/*
 * Copyright 2011 Edmunds.com, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.edmunds.etm.common.impl;

import com.edmunds.etm.common.api.ControllerPaths;
import com.edmunds.etm.common.api.UrlToken;
import com.edmunds.etm.common.thrift.UrlTokenCollectionDto;
import com.edmunds.etm.common.thrift.UrlTokenDto;
import com.edmunds.etm.common.xml.XmlMarshaller;
import com.edmunds.etm.common.xml.XmlValidationException;
import com.edmunds.etm.common.xml.XmlValidator;
import com.edmunds.zookeeper.connection.ZooKeeperConnection;
import com.google.common.collect.Lists;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.Code;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Provides direct access and allows modification of persisted {@link UrlToken} objects.
 *
 * @author Ryan Holmes
 */
@Component
public class UrlTokenRepository {

    private static final Logger logger = Logger.getLogger(UrlTokenRepository.class);

    private final ZooKeeperConnection connection;
    private final ControllerPaths controllerPaths;
    private final ObjectSerializer objectSerializer;

    @Autowired
    public UrlTokenRepository(ZooKeeperConnection connection, ControllerPaths controllerPaths,
            ObjectSerializer objectSerializer) {
        this.connection = connection;
        this.controllerPaths = controllerPaths;
        this.objectSerializer = objectSerializer;
    }

    /**
     * Gets the names of all defined tokens.
     *
     * @return list of token names
     */
    public List<String> getTokenNames() {
        List<String> tokenNames;
        try {
            tokenNames = connection.getChildren(controllerPaths.getUrlTokens(), null);
        } catch (KeeperException e) {
            logger.error("Error fetching URL token names", e);
            tokenNames = new ArrayList<String>();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        return tokenNames;
    }

    /**
     * Gets the UrlToken with the specified name.
     *
     * @param name name of the token to fetch
     * @return the requested token or null if not found
     */
    public UrlToken getToken(String name) {
        byte[] data;
        try {
            data = connection.getData(controllerPaths.getUrlToken(name), null, null);
        } catch (KeeperException e) {
            if (e.code() == Code.NONODE) {
                return null;
            } else {
                logger.error(String.format("Error fetching URL token: %s", name), e);
                return null;
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        try {
            UrlTokenDto dto = objectSerializer.readValue(data, UrlTokenDto.class);
            return UrlToken.readDto(dto);
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * Creates the specified UrlToken.
     *
     * @param token the token to create
     * @throws TokenExistsException if the token already exists
     */
    public void createToken(UrlToken token) throws TokenExistsException {
        byte[] data;
        try {
            data = objectSerializer.writeValue(UrlToken.writeDto(token));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        String path = controllerPaths.getUrlToken(token.getName());
        try {
            connection.createPersistent(path, data);
        } catch (KeeperException e) {
            if (e.code() == Code.NODEEXISTS) {
                throw new TokenExistsException(e);
            } else {
                logger.error(String.format("Error creating URL token: %s", token.getName()), e);
                throw new RuntimeException(e);
            }
        } catch (InterruptedException e) {
            logger.error(String.format("Error creating URL token: %s", token.getName()), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * Updates the specified token.
     *
     * @param token the updated token
     * @throws TokenNotFoundException if the token was not found
     */
    public void updateToken(UrlToken token) throws TokenNotFoundException {
        byte[] data;
        try {
            data = objectSerializer.writeValue(UrlToken.writeDto(token));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        String path = controllerPaths.getUrlToken(token.getName());
        try {
            connection.setData(path, data, -1);
        } catch (KeeperException e) {
            if (e.code() == Code.NONODE) {
                throw new TokenNotFoundException(e);
            } else {
                logger.error(String.format("Error updating URL token: %s", token.getName()), e);
                throw new RuntimeException(e);
            }
        } catch (InterruptedException e) {
            logger.error(String.format("Error updating URL token: %s", token.getName()), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * Deletes the specified token.
     *
     * @param name name of the token to delete
     * @throws TokenNotFoundException if the token was not found
     */
    public void deleteToken(String name) throws TokenNotFoundException {
        String path = controllerPaths.getUrlToken(name);
        try {
            connection.delete(path, -1);
        } catch (KeeperException e) {
            if (e.code() == Code.NONODE) {
                throw new TokenNotFoundException(e);
            } else {
                logger.error(String.format("Error deleting URL token: %s", name), e);
                throw new RuntimeException(e);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Deletes all persisted tokens.
     */
    public void deleteAllTokens() {
        List<String> tokenNames = getTokenNames();
        for (String name : tokenNames) {
            try {
                deleteToken(name);
            } catch (TokenNotFoundException e) {
                logger.warn(String.format("Token not found: %s", name), e);
            }
        }
    }

    /**
     * Loads URL tokens definitions from the specified XML file, optionally replacing the existing tokens.
     *
     * @param file an XML file containing token definitions
     * @param replace true to replace existing tokens, false to merge with existing
     * @thows IOException if an error occurred while reading the default tokens
     */
    public void loadTokensFromFile(File file, boolean replace) throws IOException {

        List<UrlToken> tokens = readTokensFromFile(file);

        // Delete existing tokens
        if (replace) {
            deleteAllTokens();
        }

        // Add new tokens
        for (UrlToken token : tokens) {
            try {
                createToken(token);
            } catch (TokenExistsException e) {
                logger.warn(String.format("Token already exists: %s", token.getName()), e);
            }
        }
    }

    /**
     * Reads a list of tokens from the specified XML file.
     *
     * @param file an XML file containing token definitions
     * @return list of URL tokens
     * @throws IOException if an error occurs while reading the XML
     */
    public List<UrlToken> readTokensFromFile(File file) throws IOException {
        byte[] xmlData = FileUtils.readFileToByteArray(file);

        List<UrlToken> tokens;
        try {
            tokens = unmarshalTokensFromXml(xmlData);
        } catch (XmlValidationException e) {
            String message = "Invalid default URL token XML file";
            logger.error(message, e);
            throw new IOException(message, e);
        } catch (RuntimeException e) {
            String message = "Error loading default tokens";
            logger.error(message, e);
            throw new IOException(message, e);
        }

        return tokens;
    }

    /**
     * Returns a list of tokens unmarshalled from the given XML data.
     *
     * @param xmlData an XML document containing UrlToken definitions
     * @return list of UrlToken objects
     * @throws XmlValidationException if the XML data is invalid
     */
    public List<UrlToken> unmarshalTokensFromXml(byte[] xmlData) throws XmlValidationException {

        // Validate XML
        XmlValidator xmlValidator = new XmlValidator();
        xmlValidator.validate(xmlData, XmlValidator.URL_TOKENS_XSD);

        // Unmarshall XML data and convert to UrlToken objects
        UrlTokenCollectionDto tokenCollection = XmlMarshaller.unmarshal(xmlData, UrlTokenCollectionDto.class);
        List<UrlTokenDto> tokenDtos = tokenCollection.getTokens();
        ArrayList<UrlToken> tokens = Lists.newArrayListWithCapacity(tokenDtos.size());
        for (UrlTokenDto dto : tokenCollection.getTokens()) {
            tokens.add(UrlToken.readDto(dto));
        }

        return tokens;
    }

}