001 package opendreams.proxy;
002
003 import java.util.ArrayList;
004 import java.util.List;
005 import java.util.Properties;
006
007 import openbus.util.OpenBusProxy;
008 import openbus.util.OpenBusProxyException;
009 import tecgraf.openbus.DRMAA.JobInfoHelper;
010 import tecgraf.openbus.data_service.DataAccessDenied;
011 import tecgraf.openbus.data_service.DataDescription;
012 import tecgraf.openbus.data_service.IHierarchicalDataService;
013 import tecgraf.openbus.data_service.IHierarchicalDataServiceHelper;
014 import tecgraf.openbus.data_service.ServiceFailure;
015 import tecgraf.openbus.data_service.UnstructuredDataFactory;
016 import tecgraf.openbus.data_service.UnstructuredDataHelper;
017 import tecgraf.openbus.opendreams.IOpenDreams;
018 import tecgraf.openbus.opendreams.IOpenDreamsHelper;
019 import tecgraf.openbus.opendreams.JobInfoFactory;
020 import tecgraf.openbus.opendreams.JobParameterFactory;
021 import tecgraf.openbus.opendreams.JobParameterHelper;
022 import tecgraf.openbus.opendreams.OpenDreamsJobTemplateFactory;
023 import tecgraf.openbus.opendreams.OpenDreamsJobTemplateHelper;
024 import tecgraf.openbus.project.ProjectItemDescription;
025 import tecgraf.openbus.data_service.project.ProjectItemDescriptionFactory;
026 import tecgraf.openbus.project.ProjectItemDescriptionHelper;
027
028 /**
029 * O <code>OpenDreamsProxy</code> tem como objetivo encapsular os mecanismos de
030 * acesso ao OpenDreams. Faz o login no barramento e recupara as interfaces dos
031 * serviços usados pelo cliente desse barramento.
032 *
033 * @author Tecgraf PUC-Rio
034 */
035 public class OpenDreamsProxy {
036 /**
037 * Nome do arquivo default com as propriedades para acesso ao OpenDreams.
038 */
039 public static String DEFAULT_PROPERTIES_FILE = "opendreams.properties";
040 /**
041 * Nome da propriedade que possui o nome do projeto configurado.
042 */
043 public static String PROJECT_PROPERTY = "opendreams.project.name";
044 /**
045 * O proxy para o OpenBus
046 */
047 private OpenBusProxy proxy;
048
049 /**
050 * Constrói um proxy para o serviço OpenDreams do OpenBus, usando as
051 * propriedades especificadas.
052 *
053 * @param properties as propriedades previamente configuradas
054 * @throws OpenDreamsException se houve falha na carga das propriedades
055 */
056 public OpenDreamsProxy(Properties properties) throws OpenDreamsException {
057 try {
058 this.proxy = new OpenBusProxy(properties);
059 }
060 catch (OpenBusProxyException e) {
061 throw new OpenDreamsException("Erro na construção do OpenDreamsProxy", e);
062 }
063 }
064
065 /**
066 * Constrói um proxy para o serviço OpenDreams do OpenBus, usando as
067 * propriedades do arquivo default de propriedades
068 *
069 * @see #DEFAULT_PROPERTIES_FILE
070 * @throws OpenDreamsException se houve falha na carga das propriedades
071 */
072 public OpenDreamsProxy() throws OpenDreamsException {
073 try {
074 this.proxy = new OpenBusProxy(DEFAULT_PROPERTIES_FILE);
075 }
076 catch (OpenBusProxyException e) {
077 throw new OpenDreamsException("Erro na construção do OpenDreamsProxy", e);
078 }
079 }
080
081 /**
082 * Iniciliza o contexto de acesso ao barramento, através de certificados.
083 *
084 * @throws OpenDreamsException falha no acesso ao openbus
085 */
086 public void init() throws OpenDreamsException {
087 if (!isEnabled())
088 throw new OpenDreamsException("O proxy para o serviço opendreams não" +
089 " está habilitado. Verifique as propriedades openbus.enabled e " +
090 "opendreams.component.export");
091 try {
092 proxy.open();
093 }
094 catch (OpenBusProxyException e) {
095 throw new OpenDreamsException("Erro ao abrir o proxy do OpenBus",e);
096 }
097 registerFactories();
098 }
099
100 /**
101 * Iniciliza o contexto de acesso ao barramento, através de login/senha.
102 *
103 * @param user usuário LDAP
104 * @param password senha
105 *
106 * @throws OpenDreamsException falha no acesso ao openbus
107 */
108 public void init(String user, String password) throws OpenDreamsException {
109 if (!isEnabled())
110 throw new OpenDreamsException("O proxy para o serviço opendreams não" +
111 " está habilitado. Verifique as propriedades openbus.enabled e " +
112 "opendreams.component.export");
113 try {
114 proxy.open(user, password);
115 }
116 catch (OpenBusProxyException e) {
117 throw new OpenDreamsException("Erro ao abrir o proxy do OpenBus",e);
118 }
119 registerFactories();
120 }
121
122 /**
123 * Faz o registro no ORB das fábricas necessárias para construção
124 * (marshalling) dos value types.
125 */
126 private void registerFactories() {
127 proxy.registerFactory(OpenDreamsJobTemplateHelper.id(),
128 new OpenDreamsJobTemplateFactory());
129 proxy.registerFactory(JobParameterHelper.id(), new JobParameterFactory());
130 proxy.registerFactory(JobInfoHelper.id(), new JobInfoFactory());
131 proxy.registerFactory(ProjectItemDescriptionHelper.id(),
132 new ProjectItemDescriptionFactory());
133 proxy.registerFactory(UnstructuredDataHelper.id(), new UnstructuredDataFactory());
134 }
135
136 /**
137 * Obtém o objeto registrado no openbus que implementa a interface
138 * <code>IOpenDreams</code>
139 *
140 * @return o serviço <code>IOpenDreams</code>
141 * @throws OpenDreamsException se o serviço não foi encontrado
142 */
143 public IOpenDreams getIOpenDreams() throws OpenDreamsException {
144 try {
145 return IOpenDreamsHelper.narrow(proxy.getComponent("opendreams").getFacet(
146 IOpenDreamsHelper.id()));
147 }
148 catch (OpenBusProxyException e) {
149 throw new OpenDreamsException("Erro ao recuperar o serviço opendreams",e);
150 }
151 }
152
153 /**
154 * Obtém o objeto registrado no openbus que implementa a interface
155 * <code>IOpenDreams</code>
156 *
157 * @return o serviço <code>IOpenDreams</code>
158 * @throws OpenDreamsException se o serviço não foi encontrado
159 */
160 public IHierarchicalDataService getIDataService()
161 throws OpenDreamsException {
162 try {
163 return IHierarchicalDataServiceHelper.narrow(proxy.getComponent(
164 "ProjectDataService").getFacet(IHierarchicalDataServiceHelper.id()));
165 }
166 catch (OpenBusProxyException e) {
167 throw new OpenDreamsException("Erro ao recuperar o serviço ProjectDataService",e);
168 }
169 }
170
171 /**
172 * Obtém um proxy para um projeto do usuário. O nome do projeto deve estar
173 * definido na propriedade <code>opendreams.project.name</code>. do arquivo de
174 * configuração.
175 *
176 * @return um projeto.
177 * @throws OpenDreamsException se ocorrer um erro no acesso ao serviço de
178 * projetos
179 */
180 public Project getProject() throws OpenDreamsException {
181 return getProject(getProjectName());
182 }
183
184 /**
185 * Obtém o nome do projeto usado para acesso ao OpenDreams. Essa propriedade é
186 * opcional, mas
187 *
188 * @return o nome do projeto
189 * @throws OpenDreamsException se o nome do projeto não estiver configurado
190 */
191 public String getProjectName() throws OpenDreamsException {
192 String projectName = proxy.getProperties().getProperty(PROJECT_PROPERTY);
193 if (projectName == null || projectName.isEmpty()) {
194 throw new OpenDreamsException("Propriedade " + PROJECT_PROPERTY
195 + " não definida");
196 }
197 return projectName;
198 }
199
200 /**
201 * Obtém um proxy para um projeto do usuário.
202 *
203 * @param projectName nome do projeto
204 *
205 * @return um projeto.
206 * @throws OpenDreamsException se ocorrer um erro no acesso ao serviço de
207 * projetos
208 */
209 public Project getProject(String projectName) throws OpenDreamsException {
210 IHierarchicalDataService dataService = this.getIDataService();
211 DataDescription[] rootDescList;
212 try {
213 rootDescList = dataService.getRoots();
214 if (rootDescList.length < 1) {
215 throw new OpenDreamsException("O usuário não possui projetos");
216 }
217 for (int i = 0; i < rootDescList.length; i++) {
218 DataDescription rootDesc = rootDescList[i];
219 if (!(rootDesc instanceof ProjectItemDescription)) {
220 throw new OpenDreamsException("Descritor inválido:"
221 + rootDesc.toString());
222 }
223 if (rootDesc.fName.equals(projectName)) {
224 return new Project(rootDesc, proxy.getProperties().getUser(), dataService);
225 }
226 }
227 }
228 catch (ServiceFailure e) {
229 throw new OpenDreamsException("Falha no acesso ao serviço de projetos",
230 e);
231 }
232 catch (DataAccessDenied e) {
233 throw new OpenDreamsException("Falha no acesso ao serviço de projetos",
234 e);
235 }
236 return null;
237 }
238
239 /**
240 * Obtém uma lista de proxies para os projetos do usuário.
241 *
242 * @return lista de projetos, que pode ser vazia, caso o usuário não tenha
243 * nenhum projeto.
244 * @throws OpenDreamsException se ocorrer um erro no acesso ao serviço de
245 * projetos
246 */
247 public List<Project> getAllProjects() throws OpenDreamsException {
248 ArrayList<Project> ret = new ArrayList<Project>();
249
250 IHierarchicalDataService dataService = this.getIDataService();
251 DataDescription[] rootDescList;
252 try {
253 rootDescList = dataService.getRoots();
254
255 for (int i = 0; i < rootDescList.length; i++) {
256 DataDescription rootDesc = rootDescList[i];
257 if (!(rootDesc instanceof ProjectItemDescription)) {
258 throw new OpenDreamsException("Descritor inválido:"
259 + rootDesc.toString());
260 }
261 ret.add(new Project(rootDesc, proxy.getProperties().getUser(), dataService));
262 }
263 }
264 catch (ServiceFailure e) {
265 throw new OpenDreamsException(
266 "Falha no acesso ao serviço de projetos (getAllProjects())", e);
267 }
268 catch (DataAccessDenied e) {
269 throw new OpenDreamsException(
270 "Falha no acesso ao serviço de projetos (getAllProjects())", e);
271 }
272 return ret;
273 }
274
275 /**
276 * Fecha a conexão com o openbus.
277 *
278 * @param className nome canônico da classe que implementa o serviço
279 * @return {@code true} caso o componente seja registrado ou {@code false},
280 * caso contrário.
281 * @throws OpenDreamsException Caso o proxy não esteja aberto para fazer o
282 * registro das ofertas de serviço.
283 */
284 public boolean addComponent(String className) throws OpenDreamsException {
285 try {
286 return proxy.addComponent("opendreams", IOpenDreamsHelper.id(), className);
287 }
288 catch (OpenBusProxyException e) {
289 throw new OpenDreamsException(
290 "Falha na publicação do componente opendreams", e);
291 }
292 }
293
294 /**
295 * Verifica se o proxy está habilitado.
296 * Para o proxy estar habilitado é necessário que o barramento esteja
297 * habilitado (openbus.enabled) e o componente esteja habilitado (opendreams.enabled).
298 * @return {@code true} se o proxy está habilitado ou
299 * {@code false} caso contrário.
300 */
301 public boolean isEnabled() {
302 return proxy.isEnabled()
303 && proxy.getProperties().mayExportComponent("opendreams");
304 }
305
306 /**
307 * Fecha o proxy
308 */
309 public void close() {
310 proxy.close();
311 }
312
313 /**
314 * Altera o usuário para o qual a credencial está sendo delegada.
315 * Essa delegação é feita na thread.
316 * @param user o login do usuário para o qual a credencial está sendo delegada
317 */
318 public void setThreadDelegate (String user) {
319 proxy.setThreadDelegate(user);
320 }
321 }