/*
* Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.sfc.tacker.api;
import com.google.common.base.Preconditions;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import java.util.Date;
import org.opendaylight.sfc.tacker.dto.Attributes;
import org.opendaylight.sfc.tacker.dto.Auth;
import org.opendaylight.sfc.tacker.dto.KeystoneRequest;
import org.opendaylight.sfc.tacker.dto.TackerError;
import org.opendaylight.sfc.tacker.dto.TackerRequest;
import org.opendaylight.sfc.tacker.dto.TackerResponse;
import org.opendaylight.sfc.tacker.dto.Token;
import org.opendaylight.sfc.tacker.dto.Vnf;
import org.opendaylight.sfc.tacker.util.DateDeserializer;
import org.opendaylight.sfc.vnfm.spi.SfcVnfManager;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.service.function.types.ServiceFunctionType;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.ss.rev140701.service.statistics.group.StatisticByTimestamp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TackerManager implements SfcVnfManager, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(TackerManager.class);
private static final DateDeserializer DATE_DESERIALIZER = new DateDeserializer();
private static final Gson GSON = new GsonBuilder().registerTypeAdapter(Date.class, DATE_DESERIALIZER).create();
private static final Integer CONNECT_TIMEOUT_MILLISEC = 7000;
private static final Integer READ_TIMEOUT_MILLISEC = 5000;
private final Client client;
private String baseUri;
private int tackerPort;
private int keystonePort;
private Token token;
private Auth auth;
private TackerManager(TackerManagerBuilder builder) {
Preconditions.checkNotNull(builder.getBaseUri());
Preconditions.checkArgument(builder.getTackerPort() != 0);
Preconditions.checkArgument(builder.getKeystonePort() != 0);
Preconditions.checkNotNull(builder.getAuth());
this.baseUri = builder.getBaseUri();
this.tackerPort = builder.getTackerPort();
this.keystonePort = builder.getKeystonePort();
this.auth = builder.getAuth();
client = Client.create();
client.setReadTimeout(READ_TIMEOUT_MILLISEC);
client.setConnectTimeout(CONNECT_TIMEOUT_MILLISEC);
}
@Override
public boolean createSf(ServiceFunctionType sfType) {
Token authToken = getToken();
if (authToken == null) {
LOG.error("Failed to Acquire Authentication token!");
return false;
}
WebResource webResource = client.resource(baseUri + ":" + tackerPort).path("/v1.0/vnfs");
TackerRequest tackerRequest = TackerRequest.builder()
.setVnf(Vnf.builder()
.setName(sfType.getType().getValue())
.setAttributes(Attributes.builder().setServiceType(sfType.getType().getValue()).build())
.build())
.build();
ClientResponse response = (webResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON)
.header("X-Auth-Token", authToken.getId())
.header("X-Auth-Project-Id", authToken.getTenant().getName())).post(ClientResponse.class,
GSON.toJson(tackerRequest));
if (response != null) {
switch (response.getStatus()) {
case 201:
String json = response.getEntity(String.class);
TackerResponse tackerResponse = GSON.fromJson(json, TackerResponse.class);
LOG.info("VNF successfully created.");
LOG.debug(GSON.toJson(tackerResponse));
return true;
case 401:
LOG.debug("Unauthorized! Wrong username or password.");
break;
default:
TackerError error = GSON.fromJson(response.getEntity(String.class), TackerError.class);
LOG.debug(error.toString());
break;
}
}
return false;
}
@Override
public boolean deleteSf(ServiceFunction sf) {
Token authToken = getToken();
if (authToken == null) {
LOG.error("Failed to Acquire Authentication token!");
return false;
}
String vnfId = sf.getName().getValue();
WebResource webResource = client.resource(baseUri + ":" + tackerPort).path("/v1.0/vnfs/" + vnfId);
ClientResponse response = webResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON)
.header("X-Auth-Token", authToken.getId())
.header("X-Auth-Project-Id", authToken.getTenant().getName())
.delete(ClientResponse.class);
if (response != null) {
switch (response.getStatus()) {
case 200:
LOG.info("VNF:" + vnfId + " successfully deleted.");
return true;
case 404:
LOG.debug("404 - Not Found:" + response.toString());
return false;
case 405:
LOG.debug("405 - Method not found: " + response.toString());
return false;
default:
TackerError error = GSON.fromJson(response.getEntity(String.class), TackerError.class);
LOG.debug(error.toString());
break;
}
}
return false;
}
@Override
public StatisticByTimestamp getSfStatistics(ServiceFunction sf) {
// TODO implement method
return null;
}
@Override
public void close() throws Exception {
this.client.destroy();
}
private Token getToken() {
if (this.token == null) {
this.token = requestToken();
}
if (this.token != null) {
Date currentDate = new Date();
if (!(currentDate.getTime() < token.getExpires().getTime()
&& currentDate.getTime() >= token.getIssuedAt().getTime())) {
this.token = null;
}
}
return this.token;
}
private Token requestToken() {
WebResource webResource = client.resource(baseUri + ":" + keystonePort).path("/v2.0/tokens");
KeystoneRequest keystoneRequest = new KeystoneRequest(this.auth);
ClientResponse response = webResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON)
.post(ClientResponse.class, GSON.toJson(keystoneRequest));
if (response != null) {
switch (response.getStatus()) {
case 200:
String json = response.getEntity(String.class);
JsonObject jsonObject =
GSON.fromJson(json, JsonObject.class).getAsJsonObject("access").getAsJsonObject("token");
Token token = GSON.fromJson(jsonObject, Token.class);
LOG.debug("Authentication token successfully created.");
return token;
default:
LOG.debug(response.getEntity(String.class));
break;
}
}
return null;
}
public static TackerManagerBuilder builder() {
return new TackerManagerBuilder();
}
public static class TackerManagerBuilder {
private String baseUri;
private int tackerPort;
private int keystonePort;
private Auth auth;
public String getBaseUri() {
return baseUri;
}
public TackerManagerBuilder setBaseUri(String baseUri) {
this.baseUri = baseUri;
return this;
}
public int getTackerPort() {
return tackerPort;
}
public TackerManagerBuilder setTackerPort(int tackerPort) {
this.tackerPort = tackerPort;
return this;
}
public int getKeystonePort() {
return keystonePort;
}
public TackerManagerBuilder setKeystonePort(int keystonePort) {
this.keystonePort = keystonePort;
return this;
}
public Auth getAuth() {
return auth;
}
public TackerManagerBuilder setAuth(Auth auth) {
this.auth = auth;
return this;
}
public TackerManager build() {
return new TackerManager(this);
}
}
}