View Javadoc

1   /*
2   Copyright 2011-2014 AGH-UST, http://www.agh.edu.pl
3   Faculty of Computer Science, Electronics and Telecommunications
4   Department of Computer Science 
5   
6   See the NOTICE file distributed with this work for additional
7   information regarding copyright ownership
8   
9   Licensed under the Apache License, Version 2.0 (the "License");
10  you may not use this file except in compliance with the License.
11  You may obtain a copy of the License at
12  
13    http://www.apache.org/licenses/LICENSE-2.0
14  
15  Unless required by applicable law or agreed to in writing, software
16  distributed under the License is distributed on an "AS IS" BASIS,
17  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  See the License for the specific language governing permissions and
19  limitations under the License.
20  */
21  package org.universAAL.ri.gateway.communicator.service.impl;
22  
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.FileNotFoundException;
26  import java.io.IOException;
27  import java.util.ArrayList;
28  import java.util.Collections;
29  import java.util.HashSet;
30  import java.util.List;
31  import java.util.Properties;
32  import java.util.Set;
33  
34  import org.osgi.framework.BundleContext;
35  import org.universAAL.middleware.container.osgi.util.BundleConfigHome;
36  import org.universAAL.ri.gateway.communicator.Activator;
37  import org.universAAL.ri.gateway.communicator.service.GatewayCommunicator;
38  import org.universAAL.ri.gateway.eimanager.ExportManager;
39  import org.universAAL.ri.gateway.eimanager.ImportManager;
40  
41  /**
42   * Objects of this class are responsible for starting and stopping running
43   * GatewayCommunicatorImpl workers.
44   * 
45   * @author skallz
46   * 
47   */
48  public class CommunicatorStarter {
49  
50  	/**
51  	 * Registry for active aliases.
52  	 */
53  	private static Set<String> aliases;
54  	static {
55  		aliases = Collections.synchronizedSet(new HashSet<String>());
56  	}
57  
58  	/**
59  	 * context of a related bundle.
60  	 */
61  	private BundleContext context;
62  
63  	private GatewayCommunicatorImpl communicator;
64  
65  	/**
66  	 * unique ID = ALIAS_PREFIX + custom name.
67  	 */
68  	private final String id;
69  	/**
70  	 * HTTP servlet's alias.
71  	 */
72  	private final String alias;
73  
74  	public static Properties properties;
75  
76  	/**
77  	 * Starts the worker with given ImportExportManager and ID.
78  	 * 
79  	 * @param id
80  	 *            ID
81  	 * @throws Exception
82  	 * @throws RuntimeException
83  	 */
84  	public CommunicatorStarter(final BundleContext context, final String id)
85  			throws Exception {
86  
87  		loadConfiguration();
88  		loadSecurityConfiguration();
89  
90  		final List<GatewayAddress> remoteAddresses = extractRemoteGateways();
91  
92  		this.context = context;
93  		this.id = id;
94  		this.alias = createAlias(id);
95  
96  		if (!aliases.add(alias)) {
97  			throw new IllegalArgumentException("Duplicated IDs");
98  		}
99  
100 		this.communicator = new GatewayCommunicatorImpl();
101 		this.communicator.addRemoteGateways(remoteAddresses);
102 	}
103 
104 	/**
105 	 * Starts the worker with default ID: "".
106 	 * 
107 	 * @param manager
108 	 *            a ImportExportManager reference
109 	 * @throws Exception
110 	 */
111 	public CommunicatorStarter(final BundleContext context) throws Exception {
112 		this(context, null);
113 	}
114 
115 	/**
116 	 * Util logging function.
117 	 * 
118 	 * @param format
119 	 *            format
120 	 * @param args
121 	 *            args
122 	 */
123 	static void logInfo(final String format, final Object... args) {
124 		String callingMethod = Thread.currentThread().getStackTrace()[2]
125 				.getMethodName();
126 		System.out.format("[%s] %s%n", callingMethod,
127 				String.format(format, args));
128 		// LogUtils.logInfo(Activator.mc, Activator.class.getClass(),
129 		// callingMethod.getMethodName(),
130 		// new Object[] { String.format(format, args) }, null);
131 	}
132 
133 	public synchronized GatewayCommunicator getCommunicator() {
134 		while (communicator == null) {
135 			try {
136 				this.wait();
137 			} catch (InterruptedException e) {
138 				e.printStackTrace();
139 			}
140 		}
141 		return communicator;
142 	}
143 
144 	/**
145 	 * Sets import and export managers for the communicator
146 	 * 
147 	 * @param importManager
148 	 *            import manager
149 	 * @param exportManager
150 	 *            export manager
151 	 * @throws Exception
152 	 */
153 	public synchronized void setManagers(final ImportManager importManager,
154 			final ExportManager exportManager) throws Exception {
155 		// wait for the communicator
156 		getCommunicator();
157 		this.communicator.setManagers(importManager, exportManager);
158 		this.communicator.start();
159 	}
160 
161 	private void loadConfiguration() {
162 		try {
163 			properties = new Properties();
164 			File confHome = new File(new BundleConfigHome(Activator.bc
165 					.getBundle().getSymbolicName()).getAbsolutePath());
166 			String dataDir = confHome.getPath();
167 			String separator = System.getProperty("file.separator");
168 
169 			File dataDirFile = new File(dataDir);
170 			if (!dataDirFile.exists()) {
171 				dataDirFile.mkdirs();
172 			}
173 
174 			properties
175 					.load(new FileInputStream(new File(confHome + separator,
176 							Activator.bc.getBundle().getSymbolicName()
177 									+ ".properties")));
178 
179 		} catch (FileNotFoundException e) {
180 			System.out.println(e.toString() + "\t" + e.getMessage());
181 			throw new RuntimeException("Configuration file not found");
182 		} catch (IOException e) {
183 			throw new RuntimeException("Error reading configuration file");
184 		}
185 	}
186 
187 	private void loadSecurityConfiguration() {
188 		try {
189 			
190 			SecurityManager.Instance.setAllowExportSecurityEntries(convertSecurityPropertiesToObjectNotation(Type.Export, SecurityAction.Allow));
191 			SecurityManager.Instance.setAllowImportSecurityEntries(convertSecurityPropertiesToObjectNotation(Type.Import, SecurityAction.Allow));
192 			SecurityManager.Instance.setDenyExportSecurityEntries(convertSecurityPropertiesToObjectNotation(Type.Export, SecurityAction.Deny));
193 			SecurityManager.Instance.setDenyImportSecurityEntries(convertSecurityPropertiesToObjectNotation(Type.Import, SecurityAction.Deny));
194 			
195 		} catch (Exception ex) {
196 			throw new RuntimeException(ex);
197 		}
198 	}
199 
200 	private Set<SecurityEntry> convertSecurityPropertiesToObjectNotation(
201 			Type type, SecurityAction action) {
202 
203 		String propertyname = null;
204 		switch (type) {
205 		case Export:
206 			switch (action) {
207 			case Allow:
208 				propertyname = GatewayCommunicator.EXPORT_SECURITY_CONSTRAINT_ALLOW;
209 				break;
210 			case Deny:
211 				propertyname = GatewayCommunicator.EXPORT_SECURITY_CONSTRAINT_DENY;
212 				break;
213 			}
214 			break;
215 		case Import:
216 			switch (action) {
217 			case Allow:
218 				propertyname = GatewayCommunicator.IMPORT_SECURITY_CONSTRAINT_ALLOW;
219 				break;
220 			case Deny:
221 				propertyname = GatewayCommunicator.IMPORT_SECURITY_CONSTRAINT_DENY;
222 				break;
223 			}
224 			break;
225 		}
226 
227 		final String constraints = properties.getProperty(propertyname);
228 		if (constraints == null) {
229 			throw new RuntimeException(action.toString() + " " +type.toString()
230 					+ " security constraints were not "
231 					+ "specified during middleware startup in '" + propertyname
232 					+ "' property.");
233 		}
234 		final Set<SecurityEntry> ret = new HashSet<SecurityEntry>();
235 		String[] splitted = constraints.split(",");
236 		if (splitted.length == 0) {
237 			throw new RuntimeException("At last one entry of "
238 					+ action.toString() + " " + type.toString()
239 					+ " security constraints has to be specified"
240 					+ "specified during middleware startup in '" + propertyname
241 					+ "' property.");
242 		}
243 		SecurityEntry entry = null;
244 		for(String s : splitted){
245 			entry = new SecurityEntry(action, type, s);
246 			ret.add(entry);
247 		}
248 		return ret;
249 	}
250 
251 	private List<GatewayAddress> extractRemoteGateways() {
252 		try {
253 			final String remoteGateways = properties
254 					.getProperty(GatewayCommunicator.REMOTE_GATEWAYS_PROP);
255 			if (remoteGateways == null) {
256 				throw new RuntimeException("Remote gateway addresses were not "
257 						+ "specified during middleware startup in '"
258 						+ GatewayCommunicator.REMOTE_GATEWAYS_PROP
259 						+ "' property.");
260 			}
261 			final List<GatewayAddress> ret = new ArrayList<GatewayAddress>();
262 			String[] splitted = remoteGateways.split(",");
263 			for (String hostAddress : splitted) {
264 				String[] splittedHost = hostAddress.trim().split(":");
265 				if (splittedHost.length < 2 || splittedHost.length > 3) {
266 					throw new RuntimeException(
267 							"Provided remote gateway address has bad format '"
268 									+ hostAddress
269 									+ "'. Should be colon separated!!!");
270 				}
271 				GatewayAddress addr = new GatewayAddress(splittedHost[0],
272 						Integer.valueOf(splittedHost[1]),
273 						splittedHost.length == 3 ? splittedHost[2] : null);
274 				ret.add(addr);
275 			}
276 			return ret;
277 		} catch (Exception ex) {
278 			throw new RuntimeException(ex);
279 		}
280 	}
281 
282 	static String createAlias(final String id) {
283 		if (id != null && !"".equals(id)) {
284 			return GatewayCommunicator.ALIAS_PREFIX + "-" + id;
285 		} else {
286 			return GatewayCommunicator.ALIAS_PREFIX;
287 		}
288 	}
289 
290 	public void stop() {
291 
292 	}
293 
294 }