1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.saml2.metadata.provider;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileWriter;
22 import java.io.IOException;
23
24 import org.opensaml.Configuration;
25 import org.opensaml.xml.XMLObject;
26 import org.opensaml.xml.io.Marshaller;
27 import org.opensaml.xml.io.MarshallingException;
28 import org.opensaml.xml.io.UnmarshallingException;
29 import org.opensaml.xml.util.XMLHelper;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.w3c.dom.Element;
33
34
35
36
37
38
39
40
41
42 public class FileBackedHTTPMetadataProvider extends HTTPMetadataProvider {
43
44
45 private final Logger log = LoggerFactory.getLogger(FileBackedHTTPMetadataProvider.class);
46
47
48 private File metadataBackupFile;
49
50
51
52
53
54
55
56
57
58
59
60 public FileBackedHTTPMetadataProvider(String metadataURL, int requestTimeout, String backingFilePath)
61 throws MetadataProviderException {
62 super(metadataURL, requestTimeout);
63
64 metadataBackupFile = new File(backingFilePath);
65 if (metadataBackupFile.exists()) {
66 if (metadataBackupFile.isDirectory()) {
67 throw new MetadataProviderException("Filepath " + backingFilePath
68 + " is a directory and may not be used as a backing metadata file");
69 }
70 if (!metadataBackupFile.canRead()) {
71 throw new MetadataProviderException("Filepath " + backingFilePath
72 + " exists but can not be read by this user");
73 }
74 if (!metadataBackupFile.canWrite()) {
75 throw new MetadataProviderException("Filepath " + backingFilePath
76 + " exists but can not be written to by this user");
77 }
78 } else {
79 try {
80 metadataBackupFile.createNewFile();
81 } catch (IOException e) {
82 log.error("Unable to create backing file " + backingFilePath, e);
83 throw new MetadataProviderException("Unable to create backing file " + backingFilePath, e);
84 }
85 }
86 }
87
88
89
90
91
92
93
94
95
96 protected XMLObject fetchMetadata() throws IOException, UnmarshallingException {
97 XMLObject metadata;
98 try {
99 metadata = super.fetchMetadata();
100 } catch (Exception e) {
101 log.warn("Unable to read metadata from " + getMetadataURI() + " attempting to read it from local backup", e);
102 return getLocalMetadata();
103 }
104
105
106 log.debug("Writting retrieved metadata to backup file {}", metadataBackupFile.getAbsolutePath());
107 try {
108 writeMetadataToFile(metadata);
109 } catch (Exception e) {
110 log.error("Unable to write metadata to backup file", e);
111 throw new IOException("Unable to write metadata to backup file: " + e.getMessage());
112 }
113
114 return metadata;
115 }
116
117
118
119
120
121
122
123
124
125 protected XMLObject getLocalMetadata() throws IOException, UnmarshallingException {
126 if (!(metadataBackupFile.exists() && metadataBackupFile.canRead())) {
127 throw new IOException("Unable to read metadata from backup file " + metadataBackupFile.getAbsolutePath());
128 }
129 return unmarshallMetadata(new FileInputStream(metadataBackupFile));
130 }
131
132
133
134
135
136
137
138
139 protected void writeMetadataToFile(XMLObject metadata) throws MetadataProviderException {
140 if (!metadataBackupFile.canWrite()) {
141 throw new MetadataProviderException("Unable to write to metadata backup file "
142 + metadataBackupFile.getAbsolutePath());
143 }
144
145 try {
146 Element metadataElement;
147
148
149
150 if (metadata.getDOM() != null) {
151 metadataElement = metadata.getDOM();
152 } else {
153 Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(metadata);
154 metadataElement = marshaller.marshall(metadata);
155 }
156
157 if (log.isDebugEnabled()) {
158 log.debug("Converting DOM to a string");
159 }
160 XMLHelper.writeNode(metadataElement, new FileWriter(metadataBackupFile));
161 } catch (IOException e) {
162 log.error("Unable to write metadata to file " + metadataBackupFile.getAbsolutePath(), e);
163 throw new MetadataProviderException("Unable to write metadata to file");
164 } catch (MarshallingException e) {
165 log.error("Unable to marshall metadata in order to write it to file", e);
166 throw new MetadataProviderException("Unable to marshall metadata in order to write it to file");
167 }
168 }
169 }