Merge "On openflow plugin restart, NPE in tx poller"
[controller.git] / opendaylight / config / config-persister-file-xml-adapter / src / main / java / org / opendaylight / controller / config / persist / storage / file / xml / model / Config.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.config.persist.storage.file.xml.model;
9
10 import com.google.common.base.Charsets;
11 import com.google.common.base.Optional;
12 import com.google.common.collect.Iterables;
13 import com.google.common.collect.Lists;
14 import com.google.common.io.Files;
15 import org.apache.commons.lang3.StringUtils;
16
17 import javax.xml.bind.JAXBContext;
18 import javax.xml.bind.JAXBException;
19 import javax.xml.bind.Marshaller;
20 import javax.xml.bind.Unmarshaller;
21 import javax.xml.bind.annotation.XmlElement;
22 import javax.xml.bind.annotation.XmlElementWrapper;
23 import javax.xml.bind.annotation.XmlRootElement;
24 import java.io.File;
25 import java.io.IOException;
26 import java.util.List;
27
28 @XmlRootElement(name = "persisted-snapshots")
29 public final class Config {
30
31     private List<ConfigSnapshot> snapshots;
32
33     Config(List<ConfigSnapshot> snapshots) {
34         this.snapshots = snapshots;
35     }
36
37     public Config() {
38         this.snapshots = Lists.newArrayList();
39     }
40
41     @XmlElement(name = "snapshot")
42     @XmlElementWrapper(name = "snapshots")
43     public List<ConfigSnapshot> getSnapshots() {
44         return snapshots;
45     }
46
47     public void setSnapshots(List<ConfigSnapshot> snapshots) {
48         this.snapshots = snapshots;
49     }
50
51     public void toXml(File to) {
52         try {
53
54             // TODO Moxy has to be used instead of default jaxb impl due to a bug
55             // default implementation has a bug that prevents from serializing xml in a string
56             JAXBContext jaxbContext = org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(new Class[]{Config.class}, null);
57
58             Marshaller marshaller = jaxbContext.createMarshaller();
59
60             marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
61
62             marshaller.marshal(this, to);
63         } catch (JAXBException e) {
64             throw new PersistException("Unable to persist configuration", e);
65         }
66     }
67
68     public static Config fromXml(File from) {
69         if(isEmpty(from))
70             return new Config();
71
72         try {
73             JAXBContext jaxbContext = JAXBContext.newInstance(Config.class);
74             Unmarshaller um = jaxbContext.createUnmarshaller();
75
76             return (Config) um.unmarshal(from);
77         } catch (JAXBException e) {
78             throw new PersistException("Unable to restore configuration", e);
79         }
80     }
81
82     private static boolean isEmpty(File from) {
83         return from.length() == 0 || isBlank(from);
84     }
85
86     private static boolean isBlank(File from) {
87         try {
88             return StringUtils.isBlank(Files.toString(from, Charsets.UTF_8));
89         } catch (IOException e) {
90             throw new IllegalStateException("Unexpected error reading file" + from, e);
91         }
92     }
93
94     public Optional<ConfigSnapshot> getLastSnapshot() {
95         ConfigSnapshot last = Iterables.getLast(snapshots, null);
96         return last == null ? Optional.<ConfigSnapshot>absent() : Optional.of(last);
97     }
98
99     public void addConfigSnapshot(ConfigSnapshot snap, int numberOfStoredBackups) {
100         if(shouldReplaceLast(numberOfStoredBackups) && snapshots.isEmpty() == false) {
101             snapshots.remove(0);
102         }
103         snapshots.add(snap);
104     }
105
106     private boolean shouldReplaceLast(int numberOfStoredBackups) {
107         return numberOfStoredBackups == snapshots.size();
108     }
109 }