1 package com.trendmicro.grid.acl.ds.cifs;
2
3 import net.sf.tinyjee.collections.Filter;
4 import net.sf.tinyjee.collections.FilteredCollection;
5 import net.sf.tinyjee.config.*;
6 import net.sf.tinyjee.config.documentation.PropertyDocumentation;
7 import net.sf.tinyjee.config.documentation.ResourceDocumentation;
8 import net.sf.tinyjee.config.documentation.SectionDocumentation;
9
10 import java.util.Arrays;
11 import java.util.Collection;
12 import java.util.Collections;
13
14
15
16
17
18
19
20 @SectionDocumentation(
21 name = CIFSPropertySection.NAME_SECTION,
22 description = "Specifies the configuration options for the GRID file content repository " +
23 "used by the access layer.\n" +
24 "\n" +
25 "This section configures the implementations 'CIFSFileRepository' " +
26 "and 'LocalFileRepository'.",
27 properties = {
28 @PropertyDocumentation(
29 property = CIFSPropertySection.KEY_FILENAME_HASH_KEY_ALGORITHM,
30 description = "Defines the hashing algorithm to use for creating the path names.\n" +
31 "\n" +
32 "File contents are stored in paths that are generated via the expression:\n" +
33 " path = pathPrefix + / + hash(fileContent) + fileExtension\n" +
34 "\n" +
35 "Reasonable values this property are: SHA1 or MD5 (default)"
36 ),
37 @PropertyDocumentation(
38 property = CIFSPropertySection.KEY_FILENAME_PATH_SCHEMA,
39 description = "Defines the schema that is used to translate a hash to a file path.\n" +
40 "\n" +
41 "This options takes 2 characters '0' and '/'. Every '00' is replaced by the\n" +
42 "hex value of a single byte in the file hash (single '0' values are invalid).\n" +
43 "\n" +
44 "Reasonable values for this property are:\n" +
45 " - '00000000000000000000000000000000' - creates no folders (with md5 hash)\n" +
46 " - '00/00/00/' - creates 3 levels of folders (256 on each level)\n" +
47 "\n" +
48 "(defaults to empty string => 0000/0000/0000/... is used)."
49 ),
50 @PropertyDocumentation(
51 property = CIFSPropertySection.KEY_LOCAL_REPOSITORY_PATH,
52 description = "Defines the repository path to use by the 'LocalFileRepository'."
53 ),
54 @PropertyDocumentation(
55 property = CIFSPropertySection.KEY_FILENAME_EXTENSION,
56 description = "Defines a file extension to apply for stored file contents " +
57 "(defaults to empty string => no file extension is added)."
58 ),
59 @PropertyDocumentation(
60 property = CIFSPropertySection.KEY_TEMPORARY_PATH_PREFIX,
61 description = "Defines the path inside the file repository to use for storing " +
62 "temporary file content.\n" +
63 "\n" +
64 "Note: When content is received from remote, it is first streamed to a " +
65 "temporary location in order to calculate its content hash value. After the " +
66 "hash value is known, the file is moved to the final location and therefore " +
67 "the temporary path should be located at the same physical partition to get " +
68 "the maximum efficiency out of the move operation."
69 ),
70 @PropertyDocumentation(
71 property = CIFSPropertySection.KEY_INTERNAL_URI_PREFIX,
72 description = "Allows to specify a custom value prefix to use when generating " +
73 "internally reachable URIs pointing to the content stored inside the " +
74 "file repository.\n" +
75 "\n" +
76 "By default this property is empty which will let the implementation choose " +
77 "a value for the internal URI. Setting this value has no effect on the operations " +
78 "of the access layer, however it has an influence how internalURI properties are " +
79 "set when initiating processing.\n" +
80 "\n" +
81 "Reasonable values for this property are:\n" +
82 " - ftp://hostname/path\n" +
83 " - file:///path\n" +
84 " - cifs://hostname/path\n" +
85 " - smb://hostname/path\n"
86 ),
87 @PropertyDocumentation(
88 property = CIFSPropertySection.KEY_LOCAL_REPOSITORY_PATH,
89 description = "Defines the repository path to use by the 'LocalFileRepository'."
90 )
91 }
92 )
93 @ResourceDocumentation(
94 name = CIFSPropertySection.NAME_CIFS_CONNECTION,
95 description = "Defines an outgoing connection to the GRID file repository using the CIFS protocol.",
96 properties = {
97 @PropertyDocumentation(
98 property = CIFSPropertySection.KEY_CONNECTION_DOMAIN,
99 description = "Leave empty if not required by the CIFS server."
100 ),
101 @PropertyDocumentation(
102 property = CIFSPropertySection.KEY_CONNECTION_PATH_PREFIX,
103 description = "Defines base path to use on the remote repository."
104 )
105 }
106 )
107 public class CIFSPropertySection extends PropertySection implements ConfigurationBuilder {
108
109 private static final long serialVersionUID = -4111897772847377832L;
110 private static final CIFSPropertySection sharedInstance = new CIFSPropertySection();
111
112 public static final String NAME_SECTION = "gacl-file-repository";
113 public static final String NAME_CIFS_CONNECTION = "gacl-cifs-repository";
114
115 public static final String KEY_CONNECTION_USERNAME = "username";
116 public static final String KEY_CONNECTION_PASSWORD = "password";
117 public static final String KEY_CONNECTION_DOMAIN = "domain";
118 public static final String KEY_CONNECTION_PATH_PREFIX = "pathPrefix";
119
120 public static final String KEY_FILENAME_HASH_KEY_ALGORITHM = "filenameHashKeyAlgorithm";
121 public static final String KEY_FILENAME_PATH_SCHEMA = "filenamePathSchema";
122 public static final String KEY_FILENAME_EXTENSION = "filenameExtension";
123 public static final String KEY_LOCAL_REPOSITORY_PATH = "localRepositoryPath";
124 public static final String KEY_INTERNAL_URI_PREFIX = "internalURIPrefix";
125 public static final String KEY_TEMPORARY_PATH_PREFIX = "temporaryPathPrefix";
126
127 public static PropertySection getPropertySection() {
128 Configuration config = ConfigurationContext.getInstance().getConfiguration();
129 PropertySection section = config.getPropertySection(NAME_SECTION);
130 return section == null ? sharedInstance : section;
131 }
132
133 public static Collection<Connection> getCIFSConnections() {
134 Configuration config = ConfigurationContext.getInstance().getConfiguration();
135 return new FilteredCollection<Connection>(config.getActiveConnections(), new Filter<Connection>() {
136 public boolean accept(Connection value) {
137 return NAME_CIFS_CONNECTION.equals(value.getName());
138 }
139 });
140 }
141
142
143
144
145
146
147
148
149
150
151
152 public static Connection createCIFSConnection(String hostname, String path,
153 String domain, String username, String password) {
154 Connection c = new Connection(
155 Connection.Protocol.generic, Connection.Type.outgoing, NAME_CIFS_CONNECTION, hostname, 139);
156 c.addProperty(KEY_CONNECTION_DOMAIN, domain == null ? "*" : domain);
157 c.addProperty(KEY_CONNECTION_USERNAME, username);
158 c.addProperty(KEY_CONNECTION_PASSWORD, password);
159 c.addProperty(KEY_CONNECTION_PATH_PREFIX, path);
160 return c;
161 }
162
163 {
164 setSection(NAME_SECTION);
165
166 addProperty(KEY_LOCAL_REPOSITORY_PATH, "/path/to/local/repository");
167 addProperty(KEY_FILENAME_HASH_KEY_ALGORITHM, "MD5");
168 addProperty(KEY_FILENAME_PATH_SCHEMA, "");
169 addProperty(KEY_FILENAME_EXTENSION, "");
170 addProperty(KEY_TEMPORARY_PATH_PREFIX, "temporary");
171 addProperty(KEY_INTERNAL_URI_PREFIX, "");
172 }
173
174
175
176
177 public Collection<PropertySection> buildDefaultSections() {
178 return Collections.singleton((PropertySection) new CIFSPropertySection());
179 }
180
181
182
183
184 @Override
185 public Collection<? extends Resource> buildDefaultResources() {
186 Connection devConnection = createCIFSConnection("${cifsserver}", "GRID", null, "guest", "tr3ndm1cro");
187 return Arrays.asList(devConnection);
188 }
189 }